Python PDF ライブラリ — PDF Oxide を 10 行で
PDF Oxide は Python 向けの最速 PDF ライブラリです。テキスト抽出はページ平均 0.8 ms、PyMuPDF の約 5 倍の速度で、3,830 件の PDF でパス率 100%。抽出・作成・編集をワンストップで扱えます。MIT ライセンス、Rust コア、システム依存はありません。
インストール
pip install pdf_oxide
要件: Python 3.8 以降。Linux・macOS・Windows の x86_64 / ARM64 向けにビルド済みの wheel を用意しています。コンパイラやシステムパッケージは不要です。
PDF を開く
PdfDocument で任意の PDF ファイルを開いて中身を確認できます。
from pdf_oxide import PdfDocument
doc = PdfDocument("research-paper.pdf")
print(f"Pages: {doc.page_count()}")
print(f"PDF version: {doc.version()}")
Page API
v0.3.34 から PdfDocument はイテラブルかつインデックス可能になり、遅延プロパティを持つ PdfPage オブジェクトを返します。
from pdf_oxide import PdfDocument
with PdfDocument("paper.pdf") as doc:
for page in doc: # len(doc)、doc[i]、doc[-1] すべて有効
text = page.text # 遅延評価 — アクセス時に計算
md = page.markdown(detect_headings=True)
for table in page.tables:
for row in table["rows"]:
print([cell["text"] for cell in row["cells"]])
ページのプロパティ(すべて遅延評価): text、chars、words、lines、spans、tables、images、paths、annotations、width、height、bbox。メソッド: markdown()、plain_text()、html()、render()、search()、region(x, y, w, h)。
エディタ側のページクラスは v0.3.34 で
EditorPageに改名され、PdfPageとの衝突を回避しました。
テキスト抽出
単一ページ
0 始まりのインデックスでページのプレーンテキストを抽出します。
from pdf_oxide import PdfDocument
doc = PdfDocument("report.pdf")
text = doc.extract_text(0)
print(text)
全ページ
from pdf_oxide import PdfDocument
doc = PdfDocument("book.pdf")
for i in range(doc.page_count()):
text = doc.extract_text(i)
print(f"--- Page {i + 1} ---")
print(text)
文字単位の抽出
extract_chars() はページ上の各文字について、正確な位置とフォントメタデータを含む TextChar のリストを返します。
from pdf_oxide import PdfDocument
doc = PdfDocument("paper.pdf")
chars = doc.extract_chars(0)
for ch in chars[:10]:
print(f"'{ch.char}' at ({ch.x:.1f}, {ch.y:.1f}) "
f"size={ch.font_size:.1f} font={ch.font_name} "
f"bbox={ch.bbox}")
TextChar のフィールドは以下のとおりです。
| フィールド | 型 | 説明 |
|---|---|---|
char |
str |
Unicode 文字 |
x |
float |
水平位置(ポイント) |
y |
float |
垂直位置(ポイント) |
font_size |
float |
フォントサイズ(ポイント) |
font_name |
str |
PostScript フォント名 |
bbox |
tuple[float, 4] |
バウンディングボックス (x0, y0, x1, y1) |
テキストスパン
extract_spans() は同じフォント・サイズを共有する連続した文字をスパンにまとめ、フォントメタデータ付きの構造化テキストを返します。
from pdf_oxide import PdfDocument
doc = PdfDocument("paper.pdf")
spans = doc.extract_spans(0)
for span in spans:
print(f"'{span.text}' font={span.font_name} size={span.font_size}")
Markdown 変換
PDF ページを Markdown に変換します。見出し検出は任意です。
from pdf_oxide import PdfDocument
doc = PdfDocument("paper.pdf")
md = doc.to_markdown(0, detect_headings=True)
print(md)
HTML 変換
PDF ページを HTML に変換します。
from pdf_oxide import PdfDocument
doc = PdfDocument("paper.pdf")
html = doc.to_html(0)
print(html)
画像抽出
extract_images() はページに埋め込まれたすべての画像を ImageInfo のリストで返します。コンテンツストリーム内の画像やネストされた Form XObject の画像も含まれます。
from pdf_oxide import PdfDocument
doc = PdfDocument("brochure.pdf")
images = doc.extract_image_bytes(0)
for i, img in enumerate(images):
print(f"Image {i}: {img['width']}x{img['height']} "
f"({len(img['data'])} bytes)")
with open(f"image_{i}.{img['format']}", "wb") as f:
f.write(img["data"])
extract_image_bytes() が返す各 dict のキーは次のとおりです。
| キー | 型 | 説明 |
|---|---|---|
width |
int |
画像の幅(ピクセル) |
height |
int |
画像の高さ(ピクセル) |
data |
bytes |
画像の生データ |
format |
str |
画像フォーマット(例: png, jpeg) |
バイト列から開く
メモリ上のバイト列から PDF を開けます。S3・HTTP・データベースから取得したバイナリに便利です。
from pdf_oxide import PdfDocument
doc = PdfDocument.from_bytes(pdf_bytes)
text = doc.extract_text(0)
# パスワードも指定可能:
doc = PdfDocument.from_bytes(pdf_bytes, password="secret")
ビルダー API の場合:
from pdf_oxide import Pdf
pdf = Pdf.from_bytes(existing_pdf_bytes)
pdf.save("modified.pdf")
パスワード付き PDF
暗号化された文書を開くにはコンストラクタに password= を渡します。
from pdf_oxide import PdfDocument
doc = PdfDocument("confidential.pdf", password="secret")
text = doc.extract_text(0)
print(text)
開いたあとに doc.authenticate(password) を呼び出す方法もあります。
PDF の作成
Pdf クラスは、さまざまな入力形式から PDF を生成するファクトリメソッドを提供します。
Markdown から
from pdf_oxide import Pdf
pdf = Pdf.from_markdown("# Hello World\n\nThis is a PDF.")
pdf.save("output.pdf")
HTML から
from pdf_oxide import Pdf
pdf = Pdf.from_html("<h1>Invoice</h1><p>Amount due: $42.00</p>")
pdf.save("invoice.pdf")
プレーンテキストから
from pdf_oxide import Pdf
pdf = Pdf.from_text("Plain text document.\n\nSecond paragraph.")
pdf.save("notes.pdf")
画像から
from pdf_oxide import Pdf
pdf = Pdf.from_image("scan.jpg")
pdf.save("scan.pdf")
検索
文書全体または単一ページから文字列を検索します。
from pdf_oxide import PdfDocument
doc = PdfDocument("manual.pdf")
# 全ページを検索
results = doc.search("configuration")
for r in results:
print(f"Page {r.page}: '{r.text}' at ({r.x:.0f}, {r.y:.0f})")
# 単一ページを検索
page_results = doc.search_page(0, "configuration")
エラー処理
PDF Oxide は PDF 固有のエラーを PdfError として送出し、I/O の問題には標準の Python 例外を利用します。
from pdf_oxide import PdfDocument, PdfError
try:
doc = PdfDocument("document.pdf")
text = doc.extract_text(0)
except PdfError as e:
print(f"PDF error: {e}")
except FileNotFoundError:
print("File not found")
次のステップ
- Rust 入門 – Rust から PDF Oxide を使う
- テキスト抽出 – 抽出オプションと実践レシピ
- PDF の作成 – PdfBuilder・暗号化・メタデータを含む高度な作成
- 編集 – 既存 PDF、注釈、フォームフィールドの編集
- API リファレンス – 完全な API ドキュメント