ニュースレターの内容をノートに残したい、届いた仕様変更の通知をドキュメントに転記したい、メールのやり取りを LLM に文脈として渡したい。理由は何であれ、HTML メールを Markdown にしようとしてソースを開くと、Web ページとは別次元の汚れた HTML に遭遇します。入れ子のテーブルが何層も重なり、すべての要素に style 属性が付き、見えないトラッキング画像が混ざっています。この記事では、同じメールでも「どこからコピーするか」で変換結果が別物になることを実測で示したうえで、Gmail・Outlook・.eml ファイルそれぞれからの取り出し方と、変換後の後処理までを解説します。
まず結論から — 何を残すかでルートが決まる
最初に決めるのは手段ではなく成果物です。メールの何を Markdown に残したいかで、最短ルートが変わります。
- 本文だけ残したい。対象は開いているメール数通 — ブラウザ内変換が最短です。本文ブロックの HTML をコピーして HTML to Markdown に貼り付けます。無料・登録不要で、貼り付けた内容はどこにも送信されません
- From・Subject・日付・引用スレッド・添付の一覧まで残したい。あるいは .eml ファイルが数十通ある — .eml を直接読める CLI(後述の eml2md 系)が向いています
- メールを継続的に取り込むパイプラインを作りたい — Python の
emailモジュールでパートを取り出して変換します
前提を 2 つ補足します。第一に、ブラウザ内変換ツールが扱うのは「取り出した HTML テキスト」であって、.eml ファイルそのものではありません。.eml は HTML ファイルではなく MIME コンテナなので、そのまま貼り付けても変換できません。第二に、多くのメールは multipart/alternative 形式で HTML 版と text/plain 版の両方を含んでいます。プレーンテキスト版で足りるなら、変換自体が不要なこともあります。LLM に渡す用途での形式の選び方は Markdown と HTML の LLM 向け比較で扱っています。
実測 — コピー範囲で結果が別物になる
代表的なニュースレター構造を再現した手製のサンプルメール 1 通(実在の配信メールの統計ではなくフィクスチャです)を、FormatArc の変換ツールと同一設定の Turndown 7.2.4 に通して比較しました。測定日は 2026-07-17、再現スクリプトとサンプル、結果の生データはリポジトリ内 scripts/benchmarks/html-email-to-markdown/ にあります。以下の数値はすべてこの実測によるものです。
全文ソースを貼ると 12 列のフラットな表に潰れる
サンプルの全文ソースは 6,491 バイト。この中に <table> 要素が 8 個(レイアウト用の入れ子)、style 属性が 33 個、MSO 条件付きコメントが 3 個、1x1 のトラッキングピクセルが 1 個、クリック計測用のリダイレクトリンクが 4 本含まれています。
これをそのまま変換すると、出力は 12 列のパイプ表(区切り行を含め 10 行)に押し潰されます。入れ子になったテーブルの行がすべて 1 つの表として平坦化されるため、本文の同じ文が複数のセルに重複して現れ、表としても文章としても使い物になりません。さらに <head> 内の <title> と <style> ブロックの CSS 380 バイト分が、本文テキストとして出力の先頭に漏れ出します。
この表の潰れ方は、FormatArc がテーブルを「全行を集めて 1 つのパイプ表にする」独自ルールで変換していることによる挙動です。データを並べた普通の表ではうまく働きますが、レイアウト目的の入れ子テーブルとは相性が最悪です。どのツールを使うにせよ、レイアウトテーブルを含む全文ソースをそのまま変換して良い結果になることはありません。
本文ブロックだけなら 477 文字のきれいな Markdown になる
同じメールから本文ブロック(本文を囲む要素の HTML、1,086 バイト)だけを取り出して変換すると、結果は一変します。出力は 477 文字で、見出しは #、段落は段落、リンクはリンクとして残る、そのまま使える Markdown です。style 属性 8 個はすべて除去されます。
ただし、クリック計測用のリダイレクト URL はリンク先としてそのまま残ります。これは後処理(後述)で対応します。結論はシンプルです。全文を貼らず、本文ブロックだけを貼ってください。
なぜここまで汚れているのか — HTML メール特有の構造
メールの HTML が Web ページと別物なのには理由があります。
- レイアウトがすべて入れ子テーブルなのは、メールクライアントの CSS 対応が限定的なためです。たとえば Windows 版クラシック Outlook は Word の HTML レンダリングエンジンで HTML メールを描画すると Microsoft が公式に説明しており別タブで開きます、同ドキュメントの非対応リストには
floatやposition、max-widthが並びます。テーブル以外にレイアウト手段がないのです <!--[if mso]>で始まる MSO 条件付きコメントは、Outlook にだけ別の HTML を見せる仕掛けです。変換時には HTML コメントとして扱われるため出力からは消えます- 外部 CSS が使えないクライアントが多いため、装飾はすべて style 属性として各要素に直接埋め込まれます
- 開封計測のための 1x1 画像と、クリック計測のためのリダイレクト URL(
https://click.〜/track?dest=...のような形)が本文に混ざります
メールの HTML を取り出す
変換の成否はここで決まります。クライアント別に見ていきます。
確実なのは開発者ツールで本文ブロックをコピーする方法
Gmail をはじめどの Web メールでも使える、実測の「本文ブロックだけ」に相当する取り出し方です。
- メールを開き、本文の上で右クリックして「検証」を選びます。
- 開発者ツールで、本文全体を囲んでいる要素(段落や見出しをすべて含む親要素)まで選択を広げます。
- 右クリックから「Copy」の「Copy outerHTML」を選びます。
これでヘッダーやサイドの UI を含まない、デコード済みの本文 HTML がクリップボードに入ります。
「メッセージのソースを表示」の罠 — quoted-printable
Gmail の「メッセージのソースを表示」や Thunderbird のソース表示で見えるのは、MIME メッセージ全体です。HTML パートは Content-Transfer-Encoding: quoted-printable で符号化されていることが多く、そのままコピーすると壊れた HTML になります。
Content-Type: text/html; charset="utf-8"
Content-Transfer-Encoding: quoted-printable
<td style=3D"padding:24px 32px 12px 32px; font-family:Arial, Helvetica, san=
s-serif;">
=3D は = の符号化表現で、行末の単独の = はソフト改行(デコード時に連結される印)です。RFC 2045 の Section 6.7別タブで開きます が定める規則は複数あり、=3D だけをエディタで一括置換しても正しく復元できません。デコードは MIME パート単位で行うものなので、ソース表示から取るくらいなら、後述の CLI / Python ルートに切り替えるのが正解です。
Outlook・Apple Mail・Thunderbird の場合
- Windows 版クラシック Outlook では、メッセージ本文の右クリックメニューなどからソースの表示ができ、デコード済みの HTML がエディタで開きます。ここからコピーすれば quoted-printable の問題はありません
- Apple Mail や Thunderbird では、メッセージをドラッグまたは保存操作で .eml ファイルとして書き出せます。.eml は MIME コンテナなので、テキストエディタで開いて HTML パートを探すより、次節の CLI にそのまま渡す方が速くて確実です
FormatArc で変換する — アップロードなしのブラウザ内処理
本文ブロックの HTML が取り出せたら、変換は 3 手順です。
- HTML to Markdown を開きます。
- コピーした HTML を左側に貼り付けます。
- 実行ボタンを押すと、右側に Markdown が出力されます。


変換はすべてブラウザ内の JavaScript で完結し、貼り付けた内容はどこにも送信されません。取引先とのやり取りや社内通知など、外部のサーバーに置きたくないメールを扱うときに、アップロード型の変換サービスとの違いが効いてきます。この判断基準はオンライン変換ツールの安全性にまとめています。変換の基本操作と HTML 要素の対応表は HTML を Markdown に変換するガイドを、Word や Web ページからの貼り付け整形の一般パターンは HTML 貼り付けの Markdown 化を参照してください。本記事はメール特有の話に絞ります。
変換後の後処理チェックリスト
本文ブロックだけを変換しても、メール特有の残骸は Markdown 側に残ります。公開・保存の前に次の 5 点を確認します。
- クリック計測リンクの復元。
https://click.example.com/track?dest=https%3A%2F%2F...のようなリダイレクト URL は、dest=などのパラメータを URL デコードして本来のリンク先に書き換えるか、リンク自体を外します。残った URL に機械的にアクセスして確かめる方法は、開封・クリック計測を発火させるため避けてください - トラッキングピクセルの残骸。
のような alt が空の画像参照が残っていたら削除します cid:画像の処理。本文にのような参照が残ることがあります。これはmultipart/relatedで添付された画像への内部参照で、メールの外では解決できません。画像が必要なら .eml から書き出して差し替えます 由来の余分な空白・空行の掃除- 署名・免責事項・配信停止フッター・引用スレッドをどこまで残すかの判断
.eml をまとめて変換する — CLI と Python
.eml ファイルが複数ある場合や、ヘッダー情報も残したい場合は、MIME を正しく処理できるツールに任せます。
CLI では、pip でインストールできる eml-to-md別タブで開きます が「AI エージェントに全メールへのアクセスを与えずに文脈を渡す」用途を掲げており、ヘッダー付きの Markdown を出力します。Rust 製の eml2md別タブで開きます もあります。
pip install eml-to-md
eml2md message.eml # 1 通だけ変換
eml2md *.eml -o converted/ # フォルダにまとめて変換
Python でパイプラインを組むなら、標準ライブラリの email モジュール別タブで開きますでパートを取り出し、markdownify別タブで開きます で変換します。ポイントは、バイナリモードで読むこと、policy.default を指定すること、get_body() でパートを選ぶことです。get_content() が quoted-printable や base64 のデコードを自動で行います。
import email
from email import policy
from markdownify import markdownify
with open("message.eml", "rb") as f:
msg = email.message_from_binary_file(f, policy=policy.default)
body = msg.get_body(preferencelist=("html", "plain"))
print(markdownify(body.get_content()))
このほか、HTML を経由して pandoc別タブで開きます に渡す構成や、取り出した HTML の変換だけを CLI に任せる構成(cat body.html | formatarc html-to-markdown)も組めます。FormatArc の CLI 版は formatarc npm パッケージの紹介で解説しています。
手段の比較表
| 手段 | 向いている場面 | 前提環境 | ヘッダー・スレッド | 機密メールの扱い |
|---|---|---|---|---|
| HTML to Markdown(ブラウザ) | 開いているメール数通の本文 | ブラウザのみ(無料・登録不要) | 本文のみ | ブラウザ内処理・送信なし |
| eml2md 系 CLI | .eml を数十通まとめて | pip / cargo | ヘッダー付きで出力 | ローカル処理 |
| Python(email + markdownify) | 定常的な自動パイプライン | Python | 自由に制御 | ローカル処理 |
| アップロード型 Web サービス | ほかの手段が使えないとき | ブラウザ | ツール依存 | サーバーに送信される。回数制限や課金の例も |
よくある質問
Gmail でメールの HTML ソースはどこで見られますか
メール右上のメニューから「メッセージのソースを表示」で MIME メッセージ全体を表示できます。ただしそこに見える HTML は quoted-printable で符号化されていることが多く、コピーしても壊れた HTML になります。本文だけが目的なら、本文を右クリックして「検証」から本文ブロックの outerHTML をコピーする方が確実です。
メールのレイアウトはそのまま Markdown の表になりますか
なりません。レイアウト用の入れ子テーブルは平坦化されて崩れます(実測では全文ソース 6,491 バイトが 12 列のフラットな表になりました)。本文ブロックだけを貼るのが対処法です。一方、料金表のようなデータの表は、通常のパイプ表として変換されます。
画像はどう変換されますか
src が Web 上の URL を指す画像は  の Markdown 画像として残ります。cid: で始まる参照は添付画像への内部参照のため、メールの外では表示できません。1x1 のトラッキングピクセルは変換後に削除してください。
機密メールを外部の変換ツールに貼っても安全ですか
サーバーに送信する型のツールでは、貼り付けた時点で内容が手元を離れます。FormatArc の変換はブラウザ内で完結し、送信そのものが発生しません。判断の観点はオンライン変換ツールの安全性にまとめています。
.eml ファイルをそのまま貼り付けて変換できますか
できません。.eml は HTML ではなく MIME コンテナで、ヘッダーや符号化されたパートを含むためです。1 通だけなら本文ブロックのコピーで、複数通なら eml2md 系の CLI で変換してください。
まとめ
HTML メールの Markdown 化は「どこからコピーするか」がすべてです。全文ソースを貼ると入れ子テーブルが 12 列のフラットな表に潰れ、CSS まで漏れ出しますが、本文ブロックだけなら 477 文字のきれいな Markdown になります(実測: scripts/benchmarks/html-email-to-markdown/)。開いているメール数通なら開発者ツールで本文ブロックをコピーして HTML to Markdown へ、.eml の一括処理なら eml2md 系 CLI へ、定常パイプラインなら Python の email モジュールへ。どのルートでも、トラッキングリンクとピクセルの掃除までを変換の範囲に含めて計画してください。