Skip to content

从 PyMuPDF (fitz) 迁移到 PDF Oxide

这是一份完整的 PyMuPDF→PDF Oxide 迁移指南,覆盖你现在使用的每一个 API 以及对应的替代方案。

为什么要从 PyMuPDF 迁走

四条充分的迁移理由:

  1. 快 5.8× — PDF Oxide 平均每页 0.8 ms,PyMuPDF 为 4.6 ms。体量越大差距越明显:1000 页的批处理可以在一秒内跑完,而不是五秒。
  2. MIT 许可证 — PyMuPDF 使用 AGPL,要求与它交互的所有代码都开源,否则需要购买商业许可。PDF Oxide 采用 MIT,哪里都能用,没有附加条件。
  3. 100% 稳定性 — PDF Oxide 在 PDF 测试集上的通过率是 100%。PyMuPDF 对 0.7% 的文件失败(通过率 99.3%),大约每 140 份文档就会出现一次坏输出。
  4. 内置功能齐全 — 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}")

其他迁移指南

相关页面