Skip to content

Python PDFライブラリとの比較

PDF OxideをPyMuPDF(fitz)、pypdfium2、pypdf、pdfplumber、pdfminerなどと比較します。このページでは、テキスト抽出に適したPython PDFライブラリを選ぶための、パフォーマンス、機能の網羅性、ライセンス、APIの違いを解説します。

サマリー

PDF Oxide PyMuPDF pypdfium2 pypdf pdfplumber pdfminer
平均抽出時間 0.8ms 4.6ms 4.1ms 12.1ms 23.2ms 16.8ms
成功率(3,830件のPDF) 100% 99.3% 99.2% 98.4% 98.8% 98.8%
ライセンス MIT AGPL-3.0 Apache-2.0 BSD-3 MIT MIT
言語 Rust + PyO3 C (MuPDF) C (PDFium) Pure Python Pure Python Pure Python
テキスト抽出 あり あり あり あり あり あり
文字位置 あり あり あり 一部 あり あり
画像抽出 あり あり あり あり なし なし
フォームフィールド 読み込み + 書き込み 読み込み + 書き込み 読み込みのみ 読み込み + 書き込み 読み込みのみ なし
PDF作成 あり あり なし 制限付き なし なし
PDF編集 あり あり なし あり なし なし
Markdown出力 あり なし なし なし なし なし
HTML出力 あり なし なし なし なし なし
暗号化 読み込み + 書き込み 読み込み + 書き込み 読み込みのみ 読み込み + 書き込み なし なし
PDF/A検証 あり なし なし なし なし なし
レンダリング あり あり あり なし なし なし
検索 正規表現 + 空間検索 あり あり なし なし なし
Pythonバージョン 3.8–3.14 3.8–3.12 3.8+ 3.6+ 3.8+ 3.6+
インストールサイズ 約5 MB(wheel) 約20 MB(wheel) 約3 MB(wheel) 約1 MB 約1 MB 約1 MB

パフォーマンス比較

PDF1件あたりの平均テキスト抽出時間を、3,830件のPDFからなるフルコーパスでベンチマークしました。これは公開されている3つの独立したテストスイートで構成され、すべてのPDF仕様バージョン(1.0〜2.0)、暗号化ファイル、不正な形式のドキュメント、CJKエンコーディング、複雑なレイアウト、セキュリティのエッジケースを網羅しています。各スイートが何をテストし、なぜこれらの結果が再現可能なのかについては、コーパスの詳細をご覧ください。

ライブラリ 平均 相対値 p99 成功率
PDF Oxide 0.8ms 9ms 100%
PyMuPDF 4.6ms 5.8× 28ms 99.3%
pypdfium2 4.1ms 5.1× 42ms 99.2%
pymupdf4llm 55.5ms 69× 280ms 99.1%
pdftext 7.3ms 9.1× 82ms 99.0%
pdfminer 16.8ms 21× 124ms 98.8%
pdfplumber 23.2ms 29× 189ms 98.8%
markitdown 108.8ms 136× 378ms 98.6%
pypdf 12.1ms 15.1× 97ms 98.4%

PDF Oxideは、PyO3を介してPython拡張モジュールにコンパイルされたネイティブなRustコアによってこの速度を実現しています。サブプロセスのオーバーヘッドやCライブラリの橋渡しは一切なく、Rustコードはプロセス内で直接実行されます。

信頼性

PDF Oxideは3,823件中3,823件の有効なPDFを失敗なく処理します。つまり成功率100%です。3,830件のコーパスのうち成功しなかった7件は、意図的に破損させたテスト用フィクスチャ(PDFヘッダーの欠落、ファジングで破損したカタログ、不正なxrefストリーム)です。

ライブラリ 成功した有効なPDF 成功率
PDF Oxide 3,823 / 3,823 100%
PyMuPDF 3,796 / 3,823 99.3%
pypdfium2 3,792 / 3,823 99.2%
pymupdf4llm 3,787 / 3,823 99.1%
pdftext 3,784 / 3,823 99.0%
pdfminer 3,777 / 3,823 98.8%
pdfplumber 3,777 / 3,823 98.8%
markitdown 3,771 / 3,823 98.6%
pypdf 3,762 / 3,823 98.4%

テキスト品質

PDF Oxideは、フルコーパス全体でPyMuPDFおよびpypdfium2と比較して99.5%のテキスト一致率を達成しています。品質は、抽出されたテキスト出力を1文字ずつ比較して測定しました。残りの0.5%の差は、空白の正規化とリガチャの処理によるもので、PDF Oxideはよりクリーンな出力を生成します。

ライセンス比較

ライブラリ ライセンス 商用利用 コピーレフト
PDF Oxide MIT 無制限 なし
pypdfium2 Apache-2.0 無制限 なし
PyMuPDF AGPL-3.0 商用ライセンスが必要(有料) あり
pypdf BSD-3 無制限 なし
pdfplumber MIT 無制限 なし
pdfminer MIT 無制限 なし
pdftext GPL-3.0 オープンソース化が必要 あり

PyMuPDFはAGPL-3.0ライセンスのMuPDFを使用しています。PyMuPDFを利用するソフトウェアを配布する場合、そのソフトウェアもAGPL-3.0でリリースするか、Artifexから商用ライセンスを購入する必要があります。これはSaaS製品、Webアプリケーション、および配布されるすべてのバイナリに適用されます。

PDF OxideはMITライセンスで、制限はありません。ライセンス上の義務を一切負うことなく、プロプライエタリ製品、SaaSプラットフォーム、クローズドソースアプリケーションで利用できます。

ユースケース PDF Oxide (MIT) PyMuPDF (AGPL) pypdfium2 (Apache) pypdf (BSD) pdfplumber (MIT) pdfminer (MIT)
商用製品 ライセンスが必要
クローズドソース 不可(ライセンスがある場合を除く)
SaaS/クラウド ライセンスが必要
社内ツール

API比較

テキスト抽出

PDF Oxide:

from pdf_oxide import PdfDocument

doc = PdfDocument("report.pdf")
text = doc.extract_text(0)
print(text)

PyMuPDF:

import fitz

doc = fitz.open("report.pdf")
page = doc[0]
text = page.get_text()
print(text)

pypdf:

from pypdf import PdfReader

reader = PdfReader("report.pdf")
page = reader.pages[0]
text = page.extract_text()
print(text)

pdfplumber:

import pdfplumber

with pdfplumber.open("report.pdf") as pdf:
    page = pdf.pages[0]
    text = page.extract_text()
    print(text)

pdfminer:

from pdfminer.high_level import extract_text

text = extract_text("report.pdf", page_numbers=[0])
print(text)

文字単位の抽出

PDF Oxide:

from pdf_oxide import PdfDocument

doc = PdfDocument("report.pdf")
chars = doc.extract_chars(0)
for ch in chars:
    print(f"'{ch.char}' at ({ch.bbox[0]:.1f}, {ch.bbox[1]:.1f}) "
          f"size={ch.font_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}")

pdfplumber:

import pdfplumber

with pdfplumber.open("report.pdf") as pdf:
    page = pdf.pages[0]
    for char in page.chars:
        print(f"'{char['text']}' at ({char['x0']:.1f}, {char['top']:.1f}) "
              f"size={char['size']:.1f}")

pdfminer:

from pdfminer.high_level import extract_pages
from pdfminer.layout import LTChar

for page_layout in extract_pages("report.pdf"):
    for element in page_layout:
        if hasattr(element, '__iter__'):
            for text_line in element:
                if hasattr(text_line, '__iter__'):
                    for char in text_line:
                        if isinstance(char, LTChar):
                            print(f"'{char.get_text()}' at ({char.x0:.1f}, {char.y0:.1f}) "
                                  f"size={char.size:.1f}")

画像抽出

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"])

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"])

pypdf:

from pypdf import PdfReader

reader = PdfReader("report.pdf")
page = reader.pages[0]
for i, image in enumerate(page.images):
    with open(f"image_{i}.{image.name.split('.')[-1]}", "wb") as f:
        f.write(image.data)

PDF作成

PDF Oxide:

from pdf_oxide import Pdf

pdf = Pdf.from_markdown("# Hello World\n\nThis is a PDF.")
pdf.save("output.pdf")

# Also supports HTML
pdf = Pdf.from_html("<h1>Hello</h1><p>World</p>")
pdf.save("output.pdf")

PyMuPDF:

import fitz

doc = fitz.open()
page = doc.new_page()
text_point = fitz.Point(72, 72)
page.insert_text(text_point, "Hello World", fontsize=24)
doc.save("output.pdf")

pypdf:

# pypdf can merge/modify PDFs but cannot create from scratch with text content.
# Use reportlab or fpdf2 for creation, then merge with pypdf.

暗号化されたPDF

PDF Oxide:

from pdf_oxide import PdfDocument

doc = PdfDocument("encrypted.pdf", password="password")
text = doc.extract_text(0)

PyMuPDF:

import fitz

doc = fitz.open("encrypted.pdf")
doc.authenticate("password")
page = doc[0]
text = page.get_text()

pypdf:

from pypdf import PdfReader

reader = PdfReader("encrypted.pdf")
reader.decrypt("password")
text = reader.pages[0].extract_text()

MarkdownおよびHTML出力

PDF Oxide(独自機能):

from pdf_oxide import PdfDocument

doc = PdfDocument("paper.pdf")

# Convert to Markdown with heading detection
md = doc.to_markdown(0, detect_headings=True)
print(md)

# Convert to HTML
html = doc.to_html(0)
print(html)

組み込みのMarkdownまたはHTML変換を提供するPython PDFライブラリは、他にありません。

ライブラリのプロフィール

PDF Oxide

強み:

  • Rustコアによりベンチマークで最速のテキスト抽出 — PyMuPDFより5.8倍高速
  • 3,830件のPDFコーパスで100%の成功率 — テストしたどのライブラリよりも高い信頼性
  • 抽出、作成、編集を1つのライブラリで扱える統一されたAPI
  • 見出し検出に対応した組み込みのMarkdownおよびHTMLエクスポート
  • コピーレフトの制限がないMITライセンス
  • ネイティブな準拠検証(PDF/A、PDF/UA、PDF/X)
  • 主要なすべてのプラットフォームとPython 3.8–3.14向けのビルド済みwheel
  • システム依存関係なし — wheelにすべてが含まれています

制限:

  • 比較的新しいライブラリで、コミュニティが小規模
  • テーブル抽出は、pdfplumberのアルゴリズムと比べると基本的
  • レンダリングエンジンはMuPDFほど成熟していない

PyMuPDF (fitz)

強み:

  • 成熟し、実戦で鍛えられている(MuPDFが基盤で、2005年から開発が続く)
  • 複雑なPDFに対する優れたレンダリング品質
  • 組み込みのOCR連携(Tesseract)
  • 豊富な機能セット:SVGエクスポート、ページ操作、テーブル検出

制限:

  • AGPL-3.0ライセンスにより、アプリケーションのオープンソース化または商用ライセンスの購入が必要
  • バンドルされたMuPDFにより、wheelサイズが大きい(約20 MB)
  • 組み込みのMarkdownエクスポートなし
  • 準拠検証なし

pypdfium2

強み:

  • 高速(GoogleのPDFiumエンジンが基盤)
  • Apache-2.0ライセンス — 商用利用に寛容
  • 良好なレンダリング品質

制限:

  • PDF OxideやPyMuPDFと比べて限定的なテキスト抽出API
  • PDFの作成や編集ができない
  • 読み込み専用を超えるフォームフィールドのサポートなし

pypdf

強み:

  • Pure Python — どこにでもインストール可能で、コンパイル済みの依存関係なし
  • 軽量で、よくメンテナンスされている
  • PDF操作(結合、分割、回転、暗号化)に適している
  • 大規模なコミュニティと充実したドキュメント

制限:

  • テキスト抽出はPDF Oxideより15倍遅い
  • 複雑なレイアウトではテキスト抽出品質に難がある
  • レンダリング、Markdown/HTMLエクスポート、テーブル抽出なし

pdfplumber

強み:

  • Python PDFライブラリの中で最も優れたテーブル抽出
  • 優れた文字単位の位置情報データ
  • 視覚的なデバッグツール(注釈付きのページ画像)
  • MITライセンス

制限:

  • Pure Python — PDF Oxideより29倍遅い
  • 読み込み専用 — PDFの作成や編集ができない
  • 暗号化やレンダリングなし

pdfminer

強み:

  • 詳細な文字およびレイアウト解析
  • 良好なCJKテキストサポート
  • pdfplumberや他のツールの基盤
  • MITライセンス

制限:

  • PDF Oxideより21倍遅い(Pure Pythonで未最適化)
  • 読み込み専用で、作成や編集ができない
  • 一般的なタスクに対して冗長なAPI
  • メンテナンスがあまり活発でない

どれを使うべきか

ユースケース 推奨ライブラリ
高速なテキスト抽出 PDF Oxide
商用・プロプライエタリ製品 PDF Oxide、pypdfium2、pypdf、pdfplumber、またはpdfminer
PyMuPDFの代替(MITライセンス) PDF Oxide
Markdown/HTMLからのPDF作成 PDF Oxide
準拠検証(PDF/A、PDF/X) PDF Oxide
請求書からのテーブル抽出 pdfplumber
抽出結果の視覚的なデバッグ pdfplumber
既存のMuPDF資産がある PyMuPDF(AGPLと互換性がある場合)
最小限の依存関係 pypdf(Pure Python)
詳細なレイアウト解析 pdfminer
スキャンされたドキュメントのOCR PyMuPDF

インストール

# PDF Oxide
pip install pdf_oxide

# PyMuPDF
pip install pymupdf

# pypdfium2
pip install pypdfium2

# pypdf
pip install pypdf

# pdfplumber
pip install pdfplumber

# pdfminer
pip install pdfminer.six

PDF Oxideは、Linux(x86_64、aarch64)、macOS(x86_64、arm64)、Windows(x86_64)向けのビルド済みwheelを提供します。コンパイラやシステムライブラリは不要です。

関連ページ