PDFの壁を打ち破る:数式・表・多段組対応のデータ抽出ツール MinerUの威力
ホテルのコンシェルジュのように、このツールをどのように活用できるか、導入方法、そしてサンプルコードまで、分かりやすく丁寧にご案内しますね。
MinerUは、一言でいうと「複雑なPDFなどの非構造化データを、大規模言語モデル(LLM)がすぐに使える、構造化されたデータ(MarkdownやJSON)に魔法のように変換してくれる」Pythonライブラリです。
PDFは、論文、契約書、技術仕様書、報告書など、重要な情報源でありながら、データとして扱うには非常に手間がかかります。従来のPDFパースは、レイアウトが崩れたり、表や数式が文字化けしたりと、苦労が絶えませんでした。
MinerUは、この「PDFからのデータ抽出と前処理の苦痛」を解消してくれます。
| 課題(Before MinerU) | メリット(After MinerU) |
| データ前処理の地獄: PDFから手作業でコピペ、または複雑な正規表現やカスタムスクリプトで抽出。 | LLM-Readyなデータ: 高精度で構造を保ったMarkdownやJSONを自動生成。前処理時間が激減。 |
| レイアウトの複雑さ: 多段組、ヘッダー/フッター、脚注が混在し、テキストがバラバラになる。 | 正確な読み順の確保: 人間が読む自然な順序でテキストを再構成。エージェント(Agentic Workflow)の入力として最適。 |
| 非構造化データの壁: 表や数式をデータ化するのが困難。OCRが必要な場合もある。 | リッチなデータ抽出: 表をHTMLに、数式を$\LaTeX$に変換してくれます。スキャンPDFのOCRも自動で対応。 |
| エージェント開発のボトルネック: 信頼性の低いPDF抽出結果が、エージェントの意思決定を歪ませる。 | 信頼性の高い入力: クリーンで構造化されたデータにより、エージェントの処理精度と信頼性が向上。 |
MinerUはPythonで提供されています。セットアップは非常にシンプルです。
Python 3.8以上が必要です。仮想環境(venvやcondaなど)での作業を強くお勧めします。
pipを使って簡単にインストールできます。
# ターミナルで実行
pip install mineru
OCR機能など、特定の機能を利用する場合は、追加の依存関係をインストールすることが推奨されています。
# 拡張機能を使いたい場合はこちら
# 詳細な要件は公式のGitHubリポジトリをご確認ください。
# 例: pip install mineru[ocr, all] など
ここでは、PDFファイルを読み込み、Markdown形式とJSON形式に変換する基本的なコードをご紹介します。
import os
from mineru.pdf import PDFMiner
from mineru.schemas import OutputFormat
# 1. MinerUクライアントの初期化
# 多くの設定がありますが、基本はこのままでOK
miner = PDFMiner(
# デフォルトではMarkdown形式で構造を保持
output_format=OutputFormat.MARKDOWN_MULTI_MODAL
)
# 2. 解析したいPDFファイルのパスを指定
pdf_path = "specification.pdf"
# ※ 注意: このサンプルを実行するには、作業ディレクトリに 'specification.pdf' を配置してください。
if not os.path.exists(pdf_path):
print(f"エラー: ファイル '{pdf_path}' が見つかりません。テスト用のPDFを配置してください。")
else:
print(f"'{pdf_path}' の解析を開始します...")
# 3. PDFの解析を実行
# parse_pdfメソッドは、指定したフォーマット(ここではMarkdown)の文字列を返します。
# 結果は MinerUResult オブジェクトとして返されます。
result = miner.parse_pdf(pdf_path)
# --- 結果の確認と保存 ---
# 4. Markdown形式の出力を取得し、ファイルに保存
markdown_content = result.get_content(OutputFormat.MARKDOWN_MULTI_MODAL)
output_md_path = "output_spec.md"
with open(output_md_path, "w", encoding="utf-8") as f:
f.write(markdown_content)
print("-" * 30)
print(f"Markdown形式での抽出が完了しました。ファイル: {output_md_path}")
print("\n--- 抽出されたMarkdownのプレビュー (最初の一部) ---")
print(markdown_content[:500] + "...") # 最初の500文字を表示
# 5. JSON形式の出力を取得(より構造化されたデータ向け)
# JSON形式は、段落、表、数式などがオブジェクトとして格納され、プログラムで扱いやすいです。
json_content = result.get_content(OutputFormat.JSON_READ_ORDER)
output_json_path = "output_spec.json"
with open(output_json_path, "w", encoding="utf-8") as f:
f.write(json_content)
print("-" * 30)
print(f"JSON形式での抽出が完了しました。ファイル: {output_json_path}")
print("\n--- 抽出されたJSONデータのプレビュー (最初の一部) ---")
import json
json_data = json.loads(json_content)
# JSONデータの中身の構造を確認
print(f"ルート要素のキー: {list(json_data.keys())}")
if 'pages' in json_data and json_data['pages']:
print(f"最初のページの要素数: {len(json_data['pages'][0]['elements'])}")
print("...")
Markdownデータ(output_spec.md)
LLMのコンテキストウィンドウにそのまま入力し、要約、質問応答、特定の情報抽出を行う。
例: 「この仕様書に記載されているセキュリティ要件を3点抽出せよ」
JSONデータ(output_spec.json)
データをパースし、特定のセクション(例
表データ)をデータベースに格納したり、プログラム的に処理したりする。
例: JSON内のtype: 'table'のエントリを抽出し、pandas DataFrameに変換して分析する。