从 PyMuPDF (fitz) 迁移到 PDF Oxide
这是一份完整的 PyMuPDF→PDF Oxide 迁移指南,覆盖你现在使用的每一个 API 以及对应的替代方案。
为什么要从 PyMuPDF 迁走
四条充分的迁移理由:
- 快 5.8× — PDF Oxide 平均每页 0.8 ms,PyMuPDF 为 4.6 ms。体量越大差距越明显:1000 页的批处理可以在一秒内跑完,而不是五秒。
- MIT 许可证 — PyMuPDF 使用 AGPL,要求与它交互的所有代码都开源,否则需要购买商业许可。PDF Oxide 采用 MIT,哪里都能用,没有附加条件。
- 100% 稳定性 — PDF Oxide 在 PDF 测试集上的通过率是 100%。PyMuPDF 对 0.7% 的文件失败(通过率 99.3%),大约每 140 份文档就会出现一次坏输出。
- 内置功能齐全 — Markdown 转换、HTML 输出、OCR、XFA 表单支持和 PDF 渲染全部开箱即用。PyMuPDF 做同样的事需要额外装包(
pymupdf4llm)或依赖外部工具(Tesseract)。
第 1 步:安装
pip install pdf_oxide
pip uninstall pymupdf # 可选——确认无误后再卸载
第 2 步:替换 import
# 迁移前
import fitz
# 迁移后
from pdf_oxide import PdfDocument
如果之前用 pymupdf4llm 做 Markdown 转换,可以直接删掉这个依赖——PDF Oxide 已内置。
第 3 步:API 映射
| 任务 | PyMuPDF | PDF Oxide |
|---|---|---|
| 打开 PDF | fitz.open("file.pdf") |
PdfDocument("file.pdf") |
| 页数 | doc.page_count |
doc.page_count() |
| 提取文本 | doc[0].get_text() |
doc.extract_text(0) |
| 字符位置 | doc[0].get_text("dict") |
doc.extract_chars(0) |
| 提取图像 | doc[0].get_images() + doc.extract_image(xref) |
doc.extract_images(0) |
| 搜索文本 | doc[0].search_for("query") |
doc.search_page(0, "query") |
| 表单字段 | doc[0].widgets() 或 doc.get_form_fields() |
doc.get_form_fields() |
| 加密 PDF | doc.authenticate("pw") |
PdfDocument("f.pdf", password="pw") |
| 转 Markdown | pymupdf4llm.to_markdown("file.pdf")(需单独装包) |
doc.to_markdown(0)(内置) |
| 转 HTML | 不支持 | doc.to_html(0) |
| 创建 PDF | 手动使用 insert_text() |
Pdf.from_markdown("# Title") |
| 渲染成图片 | doc[0].get_pixmap() |
doc.render_page(0) |
| XFA 表单 | 不支持 | doc.has_xfa() |
| OCR | 需要 Tesseract | 内置 PaddleOCR |
第 4 步:常见代码改写
文本提取循环
# PyMuPDF
import fitz
doc = fitz.open("report.pdf")
for page in doc:
text = page.get_text()
print(text)
# PDF Oxide
from pdf_oxide import PdfDocument
doc = PdfDocument("report.pdf")
for i in range(doc.page_count()):
text = doc.extract_text(i)
print(text)
图像提取
PyMuPDF 需要多步查找 xref。PDF Oxide 一次调用即可完成:
# PyMuPDF——多步 xref 查找
import fitz
doc = fitz.open("report.pdf")
page = doc[0]
for img in page.get_images():
xref = img[0]
base = doc.extract_image(xref)
with open(f"img.{base['ext']}", "wb") as f:
f.write(base["image"])
# PDF Oxide——一步到位
from pdf_oxide import PdfDocument
doc = PdfDocument("report.pdf")
for i, img in enumerate(doc.extract_image_bytes(0)):
with open(f"img_{i}.{img['format']}", "wb") as f:
f.write(img["data"])
加密 PDF
PyMuPDF 采用“先打开后验证”的两步模式。PDF Oxide 既支持在构造函数中传 password=,也支持打开后调用 doc.authenticate():
# PyMuPDF
import fitz
doc = fitz.open("encrypted.pdf")
doc.authenticate("password")
text = doc[0].get_text()
# PDF Oxide——用 password= 一步搞定
from pdf_oxide import PdfDocument
doc = PdfDocument("encrypted.pdf", password="password")
text = doc.extract_text(0)
Markdown 转换
PyMuPDF 需要额外的 pymupdf4llm 包;PDF Oxide 原生内置:
# PyMuPDF——需要额外安装包
import pymupdf4llm
md = pymupdf4llm.to_markdown("report.pdf")
# PDF Oxide——内置
from pdf_oxide import PdfDocument
doc = PdfDocument("report.pdf")
md = doc.to_markdown(0)
页面渲染
# PyMuPDF
import fitz
doc = fitz.open("report.pdf")
pix = doc[0].get_pixmap()
pix.save("page.png")
# PDF Oxide
from pdf_oxide import PdfDocument
doc = PdfDocument("report.pdf")
png_bytes = doc.render_page(0, dpi=150)
with open("page.png", "wb") as f:
f.write(png_bytes)
第 5 步:验证迁移
用现有测试文件分别跑两个库,比较输出:
from pdf_oxide import PdfDocument
doc = PdfDocument("your-test-file.pdf")
# 验证文本提取
text = doc.extract_text(0)
print(text[:500])
# 验证页数
print(f"Pages: {doc.page_count()}")
# 验证表单字段(如适用)
fields = doc.get_form_fields()
for f in fields:
print(f"{f.name}: {f.value}")
其他迁移指南
相关页面
- PDF Oxide vs PyMuPDF — 详细对比
- Python 快速入门 — 安装指南
- 从 PDF 提取文本 — 文本提取指南