2026 最佳 Python PDF 库对比
将 PDF Oxide 与 PyMuPDF (fitz)、pypdfium2、pypdf、pdfplumber、pdfminer 等库进行对比。本页从性能、功能覆盖、许可证和 API 差异几个维度,帮你挑选合适的 Python PDF 文本提取库。
概览
| PDF Oxide | PyMuPDF | pypdfium2 | pypdf | pdfplumber | pdfminer | |
|---|---|---|---|---|---|---|
| 平均提取时间 | 0.8ms | 4.6ms | 4.1ms | 12.1ms | 23.2ms | 16.8ms |
| 通过率(3830 个 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) | 纯 Python | 纯 Python | 纯 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 |
性能对比
每个 PDF 的平均文本提取时间,基于 3830 个 PDF 的完整语料。语料由三套公开可得的独立测试集组成,覆盖了 PDF 规范的所有版本(1.0–2.0)、加密文件、损坏文档、CJK 编码、复杂版式以及安全边缘场景。关于各测试集的内容以及结果可复现性,参见语料详情。
| 库 | 平均 | 相对 | p99 | 通过率 |
|---|---|---|---|---|
| PDF Oxide | 0.8ms | 1× | 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 代码直接在 Python 进程内运行。
稳定性
PDF Oxide 在 3823 个有效 PDF 上全部处理成功,通过率 100%。3830 个语料中未通过的 7 个文件,是有意损坏的测试用例(缺失 PDF 头、被模糊测试破坏的目录、无效 xref 流)。
| 库 | 有效 PDF 通过数 | 通过率 |
|---|---|---|
| PDF Oxide | 3823 / 3823 | 100% |
| PyMuPDF | 3796 / 3823 | 99.3% |
| pypdfium2 | 3792 / 3823 | 99.2% |
| pymupdf4llm | 3787 / 3823 | 99.1% |
| pdftext | 3784 / 3823 | 99.0% |
| pdfminer | 3777 / 3823 | 98.8% |
| pdfplumber | 3777 / 3823 | 98.8% |
| markitdown | 3771 / 3823 | 98.6% |
| pypdf | 3762 / 3823 | 98.4% |
文本质量
在整个语料上,PDF Oxide 与 PyMuPDF、pypdfium2 的文本一致率为 99.5%。质量通过逐字符比对提取结果测量得出。剩余 0.5% 的差异集中在空白字符归一化和连字处理上,PDF Oxide 的输出更干净。
许可证对比
| 库 | 许可证 | 商业使用 | Copyleft |
|---|---|---|---|
| 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")
# 同样支持 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 可以合并或修改 PDF,但无法从零创建带文本的 PDF。
# 先用 reportlab 或 fpdf2 生成,再用 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")
# 转换为 Markdown,并识别标题
md = doc.to_markdown(0, detect_headings=True)
print(md)
# 转换为 HTML
html = doc.to_html(0)
print(html)
其他 Python PDF 库都不带内置的 Markdown 或 HTML 转换功能。
各库简介
PDF Oxide
优点:
- Rust 内核带来基准测试中最快的文本提取速度——比 PyMuPDF 快 5.8×
- 在 3830 个 PDF 语料上达到 100% 通过率,是所测库中稳定性最高的
- 单个库提供统一的提取、创建、编辑 API
- 内置带标题识别的 Markdown 与 HTML 导出
- MIT 许可证,没有 copyleft(传染性开源)限制
- 原生合规校验(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 许可证,商用宽松
- 渲染质量良好
不足:
- 文本提取 API 相比 PDF Oxide 或 PyMuPDF 更为有限
- 无法创建或编辑 PDF
- 表单字段仅支持只读
pypdf
优点:
- 纯 Python,哪里都能装,没有编译依赖
- 轻量,维护良好
- 适合 PDF 操作(合并、拆分、旋转、加密)
- 社区规模大,文档充足
不足:
- 文本提取速度比 PDF Oxide 慢 15×
- 遇到复杂版式时提取质量会下降
- 无渲染、无 Markdown/HTML 输出、无表格提取
pdfplumber
优点:
- Python PDF 库中最出色的表格提取
- 字符级位置信息十分精细
- 提供可视化调试工具(带标注的页面图像)
- MIT 许可证
不足:
- 纯 Python,比 PDF Oxide 慢 29×
- 只读——无法创建或编辑 PDF
- 不支持加密与渲染
pdfminer
优点:
- 对字符与版式的分析细致
- 对 CJK 文本支持良好
- 是 pdfplumber 等工具的底座
- MIT 许可证
不足:
- 比 PDF Oxide 慢 21×(纯 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(纯 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,无需编译器或系统库。
相关页面
- 性能基准 – 完整语料基准测试结果
- Python 快速入门 – 安装与首次提取
- Python API 参考 – 完整 Python API
- vs Rust PDF 库 – Rust 生态对比