pdfplumber vs PyMuPDF – 速度、テーブル、ライセンスの比較
pdfplumber と PyMuPDF は人気のある Python PDF ライブラリですが、どちらもトレードオフを強いられます。pdfplumber はテーブル抽出に優れていますが、必要以上に 29 倍遅い。PyMuPDF は高速ですが、AGPL-3.0 ライセンスが商用利用を制限します。このページでは両者を比較し、多くのユースケースで PDF Oxide がより良い選択肢である理由を説明します。
結論: PDF Oxide は pdfplumber の 29 倍、PyMuPDF の 5.8 倍高速で、MIT ライセンスです。テキスト、画像、フォーム、暗号化、Markdown 出力、OCR のすべてを単一のライブラリで処理します。pdfplumber がまだ優位な唯一の領域は、ビジュアルデバッグ付きの複雑なテーブル抽出です。
比較概要
| pdfplumber | PyMuPDF | PDF Oxide | |
|---|---|---|---|
| ライセンス | MIT | AGPL-3.0 | MIT |
| 言語 | Pure Python | C (MuPDF) | Rust + PyO3 |
| 平均抽出時間 | 23.2ms | 4.6ms | 0.8ms |
| p99 抽出時間 | 189ms | 28ms | 9ms |
| パス率(3,830 PDF) | 98.8% | 99.3% | 100% |
| テキスト抽出 | あり | あり | あり |
| 文字位置 | あり | あり | あり |
| テーブル抽出 | 高度 | 基本的 | 基本的 |
| 画像抽出 | なし | あり | あり |
| ビジュアルデバッグ | あり | なし | なし |
| PDF 作成 | なし | あり | あり |
| PDF 編集 | なし | あり | あり |
| Markdown 出力 | なし | なし | あり |
| HTML 出力 | なし | なし | あり |
| フォームフィールド | 読み取りのみ | 読み書き | 読み書き |
| 暗号化 | なし | 読み書き | 読み書き |
| レンダリング | なし | あり | あり |
| OCR | なし | Tesseract | 内蔵(PaddleOCR) |
| インストールサイズ | ~1 MB | ~20 MB | ~5 MB |
| Python バージョン | 3.8+ | 3.8–3.12 | 3.8–3.14 |
速度ベンチマーク
3 つの独立した公開テストスイート(veraPDF, Mozilla pdf.js, DARPA SafeDocs)から構成される 3,830 件の PDF コーパスでベンチマークを実施。PDF 仕様のすべてのバージョン(1.0–2.0)、暗号化ファイル、不正ドキュメント、CJK エンコーディング、複雑なレイアウトをカバーしています。
| 指標 | pdfplumber | PyMuPDF | PDF Oxide |
|---|---|---|---|
| 平均抽出時間 | 23.2ms | 4.6ms | 0.8ms |
| p99 抽出時間 | 189ms | 28ms | 9ms |
| PDF Oxide との相対速度 | 29 倍遅い | 5.8 倍遅い | 1x |
| パス率(有効 PDF) | 98.8%(3,777/3,823) | 99.3%(3,796/3,823) | 100%(3,823/3,823) |
PyMuPDF はすべてのパースを MuPDF の C ライブラリに委譲するため、pdfplumber の約 5 倍高速です。pdfplumber はパースに pdfminer を使用し、その上に独自の空間分析レイヤーを追加しています。いずれも Pure Python です。PDF Oxide は PyO3 経由で Python プロセス内で直接実行されるコンパイル済み Rust ですべてのパース、フォントデコード、テキスト組み立てを処理するため、PyMuPDF の 5.8 倍、pdfplumber の 29 倍の優位性があります。
数値が実際に意味すること
| ワークロード | pdfplumber | PyMuPDF | PDF Oxide |
|---|---|---|---|
| 100 PDF | 2.3 秒 | 0.46 秒 | 0.08 秒 |
| 1,000 PDF | 23 秒 | 4.6 秒 | 0.8 秒 |
| 10,000 PDF | 3.9 分 | 46 秒 | 8 秒 |
| 100,000 PDF | 39 分 | 7.7 分 | 80 秒 |
少数のファイルを処理するワンオフスクリプトでは、速度差は無関係です。毎日数千のドキュメントを処理する本番パイプラインでは、39 分と 80 秒の差がアーキテクチャの決定を変えます。
テーブル抽出
テーブル抽出は、開発者が PyMuPDF よりも pdfplumber を選ぶ主な理由です。ここは pdfplumber が真に優れている領域です。
pdfplumber: 構造化されたテーブルパース
pdfplumber は罫線検出、セル結合、ビジュアルデバッグが設定可能な専用テーブル抽出を提供します:
import pdfplumber
with pdfplumber.open("invoice.pdf") as pdf:
page = pdf.pages[0]
# 構造化データとしてすべてのテーブルを抽出
tables = page.extract_tables()
for table in tables:
for row in table:
print(row)
# カスタム設定で検出を微調整
tables = page.extract_tables({
"vertical_strategy": "text",
"horizontal_strategy": "lines",
"snap_tolerance": 5,
})
# ビジュアルデバッグ: 検出されたテーブル境界を表示するページ画像をレンダリング
im = page.to_image()
im.debug_tablefinder()
im.save("debug.png")
pdfplumber は構造化された行/列データを返し、セル結合、スパニングヘッダー、罫線なしテーブルを処理します。ビジュアルデバッグオーバーレイは、難しいレイアウトでの抽出パラメータ調整に非常に有用です。
PyMuPDF: 基本的なテーブル検出
PyMuPDF は最近のバージョンでテーブル検出を追加しましたが、pdfplumber のアルゴリズムほど成熟していません:
import fitz
doc = fitz.open("invoice.pdf")
page = doc[0]
# PyMuPDF の内蔵テーブルファインダー(v1.23 で追加)
tabs = page.find_tables()
for table in tabs:
df = table.to_pandas() # pandas が必要
print(df)
PyMuPDF のテーブル抽出は、可視罫線のあるシンプルなグリッドベースのテーブルで動作します。罫線なしレイアウト、多段ヘッダー、複数行/列にまたがるセルでは苦戦します。まさに pdfplumber が最も得意とするケースです。
PDF Oxide: Markdown テーブル出力
PDF Oxide は構造化出力パイプラインの一部としてテーブルを Markdown 構文に変換します:
from pdf_oxide import PdfDocument
doc = PdfDocument("invoice.pdf")
# テーブルを検出して Markdown テーブル形式に変換
md = doc.to_markdown(0, detect_headings=True)
print(md)
# テーブルタグ付きの HTML としても利用可能
html = doc.to_html(0)
print(html)
PDF Oxide のテーブル検出は標準的なグリッドレイアウトで有効に動作し、クリーンな Markdown や HTML 出力を生成します。セル結合、罫線なしデザイン、スパニングヘッダーを含む複雑なテーブルでは、pdfplumber の専用アルゴリズムの方が頑健です。
テーブル抽出の概要
| 機能 | pdfplumber | PyMuPDF | PDF Oxide |
|---|---|---|---|
| シンプルな罫線付きテーブル | あり | あり | あり |
| 罫線なしテーブル | あり | 限定的 | 限定的 |
| セル結合 | あり | 限定的 | 限定的 |
| 多段ヘッダー | あり | なし | なし |
| 検出設定のカスタマイズ | あり | 限定的 | なし |
| ビジュアルデバッグ | あり | なし | なし |
| 出力形式 | Python リスト | pandas DataFrame | Markdown / HTML |
| 速度 | 遅い(Pure Python) | 高速 | 最速 |
複雑なテーブル抽出だけがユースケースなら、pdfplumber が最適なツールです。高速なテキスト抽出、画像抽出、PDF 作成と合わせてテーブルも必要な場合は、PDF Oxide がより広い範囲をカバーします。
テキスト抽出
プレーンテキスト抽出では、3 つのライブラリすべてが問題なく動作しますが、速度と API デザインが異なります。
pdfplumber
import pdfplumber
with pdfplumber.open("report.pdf") as pdf:
page = pdf.pages[0]
text = page.extract_text()
print(text)
PyMuPDF
import fitz
doc = fitz.open("report.pdf")
page = doc[0]
text = page.get_text()
print(text)
PDF Oxide
from pdf_oxide import PdfDocument
doc = PdfDocument("report.pdf")
text = doc.extract_text(0)
print(text)
3 つすべてが整形式の PDF に対して比較可能なテキスト出力を生成します。PDF Oxide はコーパス全体で PyMuPDF と 99.5% のテキストパリティを達成しており、残りの 0.5% の差は空白の正規化とリガチャ処理の違いです。
文字レベルの位置情報
pdfplumber と PyMuPDF はどちらも文字レベルの位置データを提供しており、空間分析、バウンディングボックス検出、カスタムレイアウト再構築に重要です。
pdfplumber
import pdfplumber
with pdfplumber.open("report.pdf") as pdf:
page = pdf.pages[0]
for char in page.chars[:10]:
print(f"'{char['text']}' at ({char['x0']:.1f}, {char['top']:.1f}) "
f"size={char['size']:.1f}")
PyMuPDF
import fitz
doc = fitz.open("report.pdf")
page = doc[0]
blocks = page.get_text("dict")["blocks"]
for block in blocks:
if "lines" in block:
for line in block["lines"]:
for span in line["spans"]:
print(f"'{span['text']}' size={span['size']:.1f}")
PDF Oxide
from pdf_oxide import PdfDocument
doc = PdfDocument("report.pdf")
chars = doc.extract_chars(0)
for ch in chars[:10]:
print(f"'{ch.char}' at ({ch.x:.1f}, {ch.y:.1f}) size={ch.font_size:.1f}")
pdfplumber はリッチなメタデータを含む文字ごとの辞書を返します。PyMuPDF はブロック/行/スパンの入れ子構造を返します。PDF Oxide は位置とフォントデータを含むフラットな文字オブジェクトを返します。
ライセンス
ここが商用プロジェクトにとって、pdfplumber と PyMuPDF の間で最も重要な違いです。
| pdfplumber | PyMuPDF | PDF Oxide | |
|---|---|---|---|
| ライセンス | MIT | AGPL-3.0 | MIT |
| 商用製品 | 可 | 商用ライセンスが必要 | 可 |
| クローズドソース SaaS | 可 | 商用ライセンスが必要 | 可 |
| Docker 配布 | 可 | 商用ライセンスが必要 | 可 |
| 社内ツール | 可 | 可 | 可 |
| オープンソースプロジェクト | 可 | 可(AGPL 互換の場合) | 可 |
PyMuPDF の AGPL 問題
PyMuPDF は AGPL-3.0 ライセンスの MuPDF をラップしています。PyMuPDF を含むソフトウェアを配布する場合(SaaS、Web アプリ、Docker コンテナを含む)、コードを AGPL でオープンソース化するか、Artifex から商用ライセンスを購入する必要があります。
Artifex は商用ライセンスの価格を公開していません。営業チームに見積もりを依頼する必要があります。ライセンスは通常アプリケーション単位で年次更新、無料枠やスタートアップ向け例外はありません。
pdfplumber と PDF Oxide はどちらも MIT
pdfplumber と PDF Oxide はどちらも MIT ライセンスです。商用、プロプライエタリ、SaaS、オープンソースなど、どのプロジェクトでも義務なく使用できます。ライセンスが主な懸念事項で pdfplumber と PyMuPDF の間で選んでいるなら、pdfplumber(または PDF Oxide)がより安全な選択です。
暗号化された PDF
暗号化の処理は、pdfplumber の機能の大きなギャップであり、パスワード保護されたドキュメントを扱う開発者にとって一般的な問題点です。
pdfplumber: 暗号化サポートなし
pdfplumber は暗号化またはパスワード保護された PDF を開くことができません。暗号化 PDF を渡すとエラーが発生します。先に別のツールでファイルを復号化する必要があります:
import pdfplumber
# 暗号化 PDF では失敗します:
with pdfplumber.open("encrypted.pdf") as pdf:
# pdfminer.pdfparser.PDFSyntaxError または同様のエラーが発生
pass
一般的な回避策は、PyMuPDF や pypdf で先にファイルを復号化し、その後 pdfplumber でテーブル抽出を行うことです。パイプラインに依存パッケージが追加されます。
PyMuPDF: 完全な暗号化サポート
import fitz
doc = fitz.open("encrypted.pdf")
doc.authenticate("password")
page = doc[0]
text = page.get_text()
PyMuPDF はユーザー/オーナーパスワード、AES-128/AES-256 暗号化をサポートし、暗号化 PDF の作成も可能です。
PDF Oxide: 完全な暗号化サポート
from pdf_oxide import PdfDocument
doc = PdfDocument("encrypted.pdf", password="password")
text = doc.extract_text(0)
PDF Oxide はすべての標準 PDF 暗号化方式(RC4, AES-128, AES-256)の読み書きに対応しています。追加の依存パッケージや前処理は不要です。
画像抽出
pdfplumber のもう一つの機能ギャップです。pdfplumber は PDF から埋め込み画像を抽出できません。
PyMuPDF
import fitz
doc = fitz.open("report.pdf")
page = doc[0]
for i, img in enumerate(page.get_images()):
xref = img[0]
base_image = doc.extract_image(xref)
with open(f"image_{i}.{base_image['ext']}", "wb") as f:
f.write(base_image["image"])
PDF Oxide
from pdf_oxide import PdfDocument
doc = PdfDocument("report.pdf")
images = doc.extract_image_bytes(0)
for i, img in enumerate(images):
with open(f"image_{i}.{img['format']}", "wb") as f:
f.write(img["data"])
パイプラインでテキストと画像の両方を PDF から抽出する必要がある場合、pdfplumber では画像側を処理できません。PyMuPDF、PDF Oxide、または pypdfium2 が必要です。
Markdown と HTML 出力
pdfplumber にも PyMuPDF にも内蔵の Markdown/HTML 変換はありません。これは PDF Oxide 独自の機能です。
from pdf_oxide import PdfDocument
doc = PdfDocument("paper.pdf")
# 見出し検出とテーブル書式付き Markdown
md = doc.to_markdown(0, detect_headings=True)
print(md)
# セマンティックタグ付き HTML
html = doc.to_html(0)
print(html)
LLM パイプライン、RAG システム、ドキュメント変換ワークフローでは、構造化された Markdown 出力により別途変換ステップが不要になります。PyMuPDF ユーザーは通常、PDF Oxide の内蔵変換の 69 倍遅い別パッケージ pymupdf4llm に頼ります。
各ライブラリの選び方
pdfplumber を選ぶべき場合:
- 複雑なテーブル抽出がメインの用途。 pdfplumber のテーブルアルゴリズムは、セル結合、罫線なしテーブル、スパニングヘッダーを他のどの Python ライブラリよりもうまく処理します。
- ビジュアルデバッグが必要。 pdfplumber は検出された罫線、文字、テーブル境界を表示するアノテーション付きページ画像をレンダリングでき、難しいドキュメントでの抽出チューニングに非常に有用です。
- Pure Python ソリューションを好む。 コンパイル済み依存パッケージなしで、Python が動く場所ならどこでもインストールできます。
- 速度が問題にならない。 一度に 100 ファイル未満を処理するなら、平均 23ms はまったく問題ありません。
PyMuPDF を選ぶべき場合:
- 既に MuPDF の商用ライセンスを持っている場合で、MuPDF 固有のレンダリングや SVG エクスポートに依存している。
- 高精度のレンダリングが必要。 MuPDF のレンダリングエンジンは成熟しており、複雑な PDF をうまく処理します。
- プロジェクトが AGPL 互換。 AGPL や互換ライセンスのオープンソースソフトウェアを構築しているなら、PyMuPDF のライセンスは問題になりません。
- Tesseract 経由の OCR が必要。 PyMuPDF にはスキャンドキュメント用の Tesseract 連携が内蔵されています。
PDF Oxide を選ぶべき場合:
- 速度と幅広い機能カバレッジが必要。 平均 0.8ms の抽出 — PyMuPDF の 5.8 倍、pdfplumber の 29 倍高速 — テキスト、画像、フォーム、作成、暗号化が単一ライブラリで。
- 速度を犠牲にせず MIT ライセンスが必要。 pdfplumber は MIT だが遅い。PyMuPDF は高速だが AGPL。PDF Oxide は MIT かつ高速。
- Markdown や HTML 出力が必要。 LLM パイプラインや RAG システム向けの内蔵構造化変換。
- パーミッシブライセンスで暗号化 PDF サポートが必要。 pdfplumber は暗号化に対応できない。PyMuPDF は対応するが AGPL コンプライアンスが必要。PDF Oxide は MIT で暗号化を処理。
- 抽出、作成、編集を単一ライブラリで。 pdfplumber も PyMuPDF も PDF ワークフローの一部に別ツールが必要。PDF Oxide は抽出、作成、編集、レンダリング、バリデーションをカバー。
PDF Oxide + pdfplumber を組み合わせて使用:
高速なテキスト抽出、画像抽出、複雑なテーブル解析が必要なパイプラインでは、一般的なパイプラインに PDF Oxide、テーブルに pdfplumber を使用:
from pdf_oxide import PdfDocument
import pdfplumber
# PDF Oxide で高速テキストと画像の抽出
doc = PdfDocument("report.pdf")
text = doc.extract_text(0)
images = doc.extract_image_bytes(0)
# pdfplumber で複雑なテーブル抽出
with pdfplumber.open("report.pdf") as pdf:
tables = pdf.pages[0].extract_tables()
インストール
# pdfplumber
pip install pdfplumber
# PyMuPDF
pip install pymupdf
# PDF Oxide
pip install pdf_oxide
3 つすべてが pip でインストール可能です。pdfplumber と PDF Oxide は MIT ライセンスです。PyMuPDF は AGPL-3.0 — 商用プロジェクトに追加する前にライセンスへの影響を確認してください。
結論
pdfplumber と PyMuPDF はそれぞれ問題の一部を解決します。PDF Oxide はすべてを解決します。
| あなたの優先事項 | 最適な選択 |
|---|---|
| 最大の速度 | PDF Oxide(0.8ms — pdfplumber の 29 倍高速) |
| 複雑なテーブル抽出 | pdfplumber(ビジュアルデバッグ、セル結合) |
| パーミッシブライセンス + 速度 | PDF Oxide — pdfplumber は MIT だが遅い、PyMuPDF は高速だが AGPL |
| 暗号化 PDF | PDF Oxide または PyMuPDF — pdfplumber は復号化不可 |
| 画像抽出 | PDF Oxide または PyMuPDF — pdfplumber は画像サポートなし |
| Markdown/HTML 出力 | PDF Oxide — 内蔵変換を持つ唯一のライブラリ |
| Tesseract なしの OCR | PDF Oxide — 内蔵 PaddleOCR |
| すべてを 1 ライブラリで | PDF Oxide — 抽出、作成、編集、暗号化、OCR |
ワークフロー全体が複雑なテーブル抽出(罫線なしテーブル、セル結合、ビジュアルデバッグ)でなければ、PDF Oxide は pdfplumber と PyMuPDF の両方を置き換えます — より高速、より多機能、MIT ライセンス。
10 秒で始めましょう:
pip install pdf_oxide
from pdf_oxide import PdfDocument
doc = PdfDocument("report.pdf")
text = doc.extract_text(0) # pdfplumber の 29 倍高速
md = doc.to_markdown(0) # 内蔵、別パッケージ不要
images = doc.extract_image_bytes(0) # pdfplumber にはできない
関連ページ
- PDF Oxide vs PyMuPDF – 移行ガイド付きの詳細比較
- PDF Oxide vs pdfplumber – コード例付きの詳細比較
- Python PDF ライブラリとの比較 – 全 Python ライブラリの比較
- パフォーマンスベンチマーク – コーパス全体のベンチマーク手法
- PDF からのテーブル抽出 – テーブル抽出ガイド
- Python で始める – インストールと最初の抽出