PythonでPDFをMarkdownに変換する方法
PDFのMarkdown変換は、RAGパイプラインやLLMワークフローの標準的な前処理になりました。Markdownなら、モデルが構造を理解するために使う見出しや表を、わずかなトークン数で保持できます。Pythonには良い選択肢がいくつかあり、それぞれに現実的なトレードオフがあります。ここでは重要な4つを、動くコード付きで紹介します。
なぜMarkdownなのか、そしてなぜ見た目より難しいのか
LLMはMarkdownを非常にうまく扱います。見出しはセクションの境界を示し、パイプ表は表形式データの整列を保ち、リストはリストのまま残ります。PDFから生テキストを抽出してモデルに与えると、それがすべて失われます。かといってPDFバイナリをそのまま渡すのは、ほとんどのパイプラインでは選択肢になりません。だからこそ、真剣なRAGスタックのほぼすべてが、チャンク分割と埋め込みの前にドキュメントをMarkdownに変換するのです。
難しいのは、PDFには構造が含まれていないことです。含まれているのはx/y座標に配置された文字だけです。変換ツールは、どの行が見出しか(フォントサイズから)、どの単語が表を構成するか(整列から)、読み順はどうか(レイアウト解析から)をリバースエンジニアリングしなければなりません。この処理の巧拙はライブラリによって大きく異なり、だからこそ選択が重要になります。
もう1つの厄介事:スキャンPDFにはテキストがまったく含まれておらず、ページの画像しかありません。以下の選択肢のうち、OCR経由でこれを処理できるのは一部だけです。
選択肢1:PyMuPDF4LLM — 高速・軽量
PyMuPDF4LLMは、PyMuPDF(fitz)の上にLLMパイプライン専用に作られた薄いレイヤーです。pip install pymupdf4llm のあと md = pymupdf4llm.to_markdown("doc.pdf") — この1行だけで、非常に高速です。ほとんどのドキュメントを1秒未満で処理します。
フォントサイズから見出しを検出し、表をパイプ表としてレンダリングし、LlamaIndexやLangChainに直接取り込めるメタデータ付きのページチャンクを出力できます。レポート、ドキュメント、特殊なレイアウトのない論文といった、素直なレイアウトのデジタル生成PDFには最良のデフォルトです。
限界:OCRがないため、スキャンページは空で返ってきます。複雑な多段組レイアウトや込み入った表は崩れることがあります。内部のヒューリスティクスが深いレイアウト解析より速度を優先しているためです。ライセンス面の注意:PyMuPDFはAGPLです。社内ツールなら問題ありませんが、商用プロダクトに組み込んで出荷する前に法務に確認してください。
選択肢2:Marker — 最高品質、ただしGPUが必要
Markerは、レイアウト検出、読み順、表構造にディープラーニングモデルのパイプラインを使い、オープンソースの選択肢の中で最も忠実なMarkdownを生成します。多段組の学術論文、複雑な表、さらには数式まで処理できます。
その代償はインフラです。数ギガバイトのモデルウェイト、実用的な速度を出すためのGPU(CPUでも動きますが遅く、1ドキュメントに数十秒かかることも珍しくありません)、そして本番環境やサーバーレス環境へのデプロイに相当な労力を要する重い依存関係ツリーです。
難しいドキュメントでの出力品質が最優先で、ハードウェアがあるならMarkerを選んでください。GPUマシンで学術コーパスを一括変換するのが得意分野です。軽量なサービスやサーバーレス関数では、運用の重さが通常ネックになります。
選択肢3:MarkItDown — Microsoft製の全形式コンバーター
MarkItDownはMicrosoftのオープンソースの「なんでもMarkdown化」ライブラリです。pip install markitdown のあと MarkItDown().convert("doc.pdf").text_content で使えます。強みは対応範囲の広さで、同じAPIでPDF、DOCX、PPTX、XLSX、HTMLなどを変換できます。LLMのデータ準備用として一気に広まった理由もここにあります。
PDFに限って言えば、抽出処理は専用ライブラリよりシンプルです。基本的なテキスト抽出に頼っているため、見出し検出や表の忠実度はPyMuPDF4LLMやMarkerに及ばず、スキャンPDFには追加のOCRセットアップが必要です。
多くのファイル形式を1つの依存関係でそこそこの品質でカバーしたいとき(「アップロードされたものは何でも受け付ける」社内取り込みスクリプトなど)にMarkItDownを選んでください。PDFの最高品質の出力が目的なら他を選びましょう。
選択肢4:ホスト型API — 依存関係ゼロ
4つ目の選択肢は、変換をローカルで実行しないことです。パースAPIにPDFをPOSTしてMarkdownを受け取ります。ParseJetの場合:resp = httpx.post("https://api.parsejet.com/v1/parse/auto/file", headers={"Authorization": "Bearer KEY"}, files={"file": open("doc.pdf", "rb")}) — JSONレスポンスの"text"フィールドがMarkdownです。
この方法にはスキャンページ用のOCRが組み込まれており、モデルウェイトもネイティブライブラリのインストールも不要で、サーバーレス関数でもコンテナでもノートブックでもまったく同じように動きます。AGPLの問題も丸ごと回避できます。トレードオフはネットワークの往復と、無料枠を超えたあとのドキュメント単位のコストです(無料で月300クレジット、PDF 1件は3クレジット)。
パイプラインを今日中に動かしたいとき、PDFにスキャンが混ざっているとき、重い依存関係が痛いところにデプロイするとき(Lambda、Cloud Run、Vercel)はAPIを選んでください。
結局どれを使うべきか
デジタル生成PDF、シンプル〜中程度のレイアウト、速度重視:PyMuPDF4LLM。純Pythonでは労力対品質の比率が最良です。
難しいドキュメント(多段組の論文、複雑な表)でGPUがある:Marker。出力品質でこれに勝るオープンソースはありません。
多種多様なファイル形式を1つのライブラリで、品質はそこそこで良い:MarkItDown。
スキャンPDFが混ざる、サーバーレスにデプロイする、依存関係の管理を一切したくない:ホスト型API。HTTP呼び出し1回でOCR込み、どのドキュメントでも同じ出力スキーマです。
完全な例:PDFフォルダをMarkdownファイルに
どの方法を選んでも、パイプラインの形は同じです — 反復して、変換して、書き出す。ここではAPIを使った例を示します(ローカルで実行するなら内側の呼び出しを pymupdf4llm.to_markdown() に差し替えてください):
import httpx; from pathlib import Path — そして Path("pdfs/").glob("*.pdf") の各pdfについて:resp = httpx.post("https://api.parsejet.com/v1/parse/auto/file", headers={"Authorization": "Bearer KEY"}, files={"file": pdf.read_bytes()}); Path("md/", pdf.stem + ".md").write_text(resp.json()["text"], encoding="utf-8") を実行します。
RAGに取り込む場合は、固定文字数ではなく見出し単位でMarkdownをチャンク分割してください。見出しを意識したチャンクはセクションを分断せず、検索精度が劇的に向上します。その構造の忠実さこそ、変換ステップを丁寧にやる価値があった理由です。
よくある質問
PDFをMarkdownに変換する最良のPythonライブラリは?
デジタル生成PDFなら、速度と品質のバランスが最も良いのはPyMuPDF4LLMです。GPUが使えて難しいレイアウトを扱うならMarkerが最高品質です。スキャンPDFや依存関係ゼロのデプロイには、ParseJetのようなホスト型APIがOCRと構造抽出をHTTP呼び出し1回で処理します。
PythonでスキャンPDFをMarkdownに変換するには?
スキャンページにはテキストが含まれていないため、OCRが必要です。ローカルでやるならOCRエンジンを自分で組み込むことになります。より簡単なのはOCR内蔵のAPIを使う方法で、ParseJetは画像ベースのページを検出して同じリクエスト内で自動的にOCRします。
MarkItDownはPDFのMarkdown変換に向いていますか?
MarkItDownの強みは、多くの形式(PDF、DOCX、PPTX、XLSX)を1つのライブラリで変換できることです。PDFに限れば構造検出はPyMuPDF4LLMやMarkerよりシンプルで、中程度の品質で良ければ十分ですが、見出しや表を忠実に抽出したい場合の最良の選択ではありません。
RAGではなぜプレーンテキストでなくMarkdownに変換するのですか?
Markdownは、プレーンテキストでは潰れてしまう見出し・リスト・表を保持します。見出しを意識したチャンク分割は検索精度が高く、LLMは構造を文脈理解に使います。しかもトークンコストはプレーンテキストとほぼ同じです。
何もインストールせずにPythonでPDFをMarkdownに変換できますか?
はい。httpxやrequestsでパースAPIをHTTP経由で呼び出してください。ParseJetの /v1/parse/auto/file にファイルをPOSTすると、レスポンスの"text"フィールドがMarkdownです。無料のAPIキーには月300クレジットが含まれます。
関連ツール
PDF to Markdown Converter
Convert PDF to Markdown online for free. Preserves headings, lists, tables, and code blocks. No signup required — try it instantly or automate via API.
PDF to JSON Converter
Convert PDF to JSON online for free. Get text, title, and metadata as structured JSON — ready for your app, database, or AI pipeline. API included.
Word to Markdown Converter
Convert Word documents (DOCX) to Markdown online for free. Headings, lists, and tables preserved. No signup — or automate DOCX to MD conversion via API.