跳到主要内容
Python 处理 PDF 工具——PyMuPDF 的安装与使用 | 极客日志
Python
Python 处理 PDF 工具——PyMuPDF 的安装与使用 PyMuPDF 是 MuPDF 的 Python 绑定,支持 PDF、XPS 等多种文档格式的处理。其核心功能,包括文本提取、图像渲染、页面增删改查及文档合并拆分。内容涵盖安装步骤、基础 API 使用示例以及常见操作实践,帮助开发者高效集成 PDF 处理能力。
Ne0 发布于 2025/2/6 更新于 2026/5/24 17 浏览PyMuPDF 简介与安装
1. PyMuPDF 简介
1.1 MuPDF 概述
在介绍 PyMuPDF 之前,首先需要了解其底层库 MuPDF。从命名形式可以看出,PyMuPDF 是 MuPDF 的 Python 接口形式。
MuPDF 是一个轻量级的 PDF、XPS 和电子书查看器。它由软件库、命令行工具和各种平台的查看器组成。
渲染能力 :MuPDF 中的渲染器专为高质量抗锯齿图形量身定制。它以精确到像素的几分之一内的度量和间距呈现文本,以在屏幕上再现打印页面的外观时获得最高保真度。
格式支持 :这个观察器很小,速度很快,但是很完整。它支持多种文档格式,如 PDF、XPS、OpenXPS、CBZ、EPUB 和 FictionBook 2。
功能 :您可以使用移动查看器对 PDF 文档进行注释和填写表单。命令行工具允许您注释、编辑文档,并将文档转换为其他格式,如 HTML、SVG、PDF 和 CBZ。您还可以使用 Javascript 编写脚本来操作文档。
1.2 PyMuPDF 特性
PyMuPDF(当前版本 1.18.17) 是支持 MuPDF(当前版本 1.18.*) 的 Python 绑定。
使用 PyMuPDF,你可以访问扩展名为 .pdf、.xps、.oxps、.cbz、.fb2 或 .epub。此外,大约 10 种流行的图像格式也可以像文档一样处理:.png、.jpg、.bmp、.tiff 等。
对于所有支持的文档类型可以:
解密文件
访问元信息、链接和书签
以栅格格式(PNG 和其他格式)或矢量格式 SVG 呈现页面
搜索文本
提取文本和图像
转换为其他格式:PDF, (X)HTML, XML, JSON, text
对于 PDF 文档,存在大量的附加功能:它们可以创建、合并或拆分。页面可以通过多种方式插入、删除、重新排列或修改 (包括注释和表单字段)。
可以提取或插入图像和字体,完全支持嵌入式文件。pdf 文件可以重新格式化,以支持双面打印,色调分离,应用标志或水印。
完全支持密码保护:解密、加密、加密方法选择、权限级别和用户/所有者密码设置。
支持图像、文本和绘图的 PDF 可选内容概念,可以访问和修改低级 PDF 结构。
命令行模块 "python -m fitz..." 具有以下特性的多功能实用程序:
加密/解密/优化
创建子文档
文档连接
图像/字体提取
完全支持嵌入式文件
保存布局的文本提取 (所有文档)
新:布局保存文本提取!
脚本 通过子命令 提供不同格式的文本提取。特别有趣的当然是布局保存,它生成的文本尽可能接近原始物理布局,周围有图像的区域,或者在表格和多列文本中复制文本。
fitzcli.py
"gettext"
2. 安装方法 PyMuPDF 可以从源码安装,也可以从 wheels 安装。
对于 Windows, Linux 和 Mac OSX 平台,在 PyPI 的下载部分有 wheels。这包括 Python 64 位版本 3.6 到 3.9。Windows 版本也有 32 位版本。从最近开始,Linux ARM 架构也出现了一些问题——查找平台标签 manylinux2014_aarch64。
除了标准库,它没有强制性的外部依赖项。只有在安装了某些包时,才会有一些不错的方法:
Pillow:当使用 Pixmap.pil_save() 和 Pixmap.pil_tobytes() 时需要
fontTools:当使用 Document.subset_fonts() 时需要
pymupdf-fonts 是一个不错的字体选择,可以用于文本输出方法
关于命名 fitz 的说明 这个库的标准 Python 导入语句是 import fitz。这是有历史原因的:
MuPDF 的原始渲染库被称为 Libart。
在 Artifex 软件获得 MuPDF 项目后,开发的重点转移到编写一种新的现代图形图书馆称为 "Fitz"。Fitz 最初是作为一个研发项目,以取代老化的 Ghostscript 图形库,但却成为了 MuPDF 的渲染引擎 (引用自维基百科)。
3. 基础使用
3.1 导入库,查看版本 import fitz
print (fitz.__doc__)
3.2 打开文档 doc = fitz.open (filename)
这将创建 Document 对象 doc。文件名必须是一个已经存在的文件的 python 字符串。
也可以从内存数据 打开文档,或创建新的空 PDF。您还可以将文档用作上下文管理器。
3.3 Document 的方法和属性 方法/属性 描述 Document.page_count页数 (int) Document.metadata元数据 (dict) Document.get_toc()获取目录 (list) Document.load_page()读取页面
>>> doc.page_count
1
>>> doc.metadata
{
'format' : 'PDF 1.7' ,
'title' : '' ,
'author' : '' ,
'subject' : '' ,
'keywords' : '' ,
'creator' : '' ,
'producer' : '福昕阅读器 PDF 打印机 版本 10.0.130.3456' ,
'creationDate' : "D:20210810173328+08'00'" ,
'modDate' : "D:20210810173328+08'00'" ,
'trapped' : '' ,
'encryption' : None
}
3.4 获取元数据 PyMuPDF 完全支持标准元数据。Document.metadata 是一个具有以下键的Python 字典 。
它适用于所有文档类型,但并非所有条目都始终包含数据。元数据字段为字符串,如果未另行指示,则为无。还要注意的是,并非所有数据都始终包含有意义的数据——即使它们不是一个都没有。
Key Value producer producer (producing software) format format: 'PDF-1.4', 'EPUB', etc. encryption encryption method used if any author author modDate date of last modification keywords keywords title title creationDate date of creation creator creating application subject subject
3.5 获取目标大纲
3.6 页面 (Page) 操作
您可以将页面呈现为光栅或矢量(SVG)图像,可以选择缩放、旋转、移动或剪切页面。
您可以提取多种格式 的页面文本和图像,并搜索文本字符串。
对于 PDF 文档,可以使用更多的方法向页面添加文本或图像。
首先,必须创建一个页面 Page。这是 Document 的一种方法:
page = doc.load_page(pno)
page = doc[pno]
这里可以使用任何整数。负数从末尾开始倒数,所以 doc[-1] 是最后一页,就像 Python 序列一样。
for page in doc:
for page in reversed (doc):
for page in doc.pages(start, stop, step):
a. 检查页面的链接、批注或表单字段 使用某些查看器软件显示文档时,链接显示为'热点区域'。如果您在光标显示手形符号时单击,您通常会被带到该热点区域中编码的标记。以下是如何获取所有链接:
links 是一个 Python 字典列表。
还可以作为迭代器使用:
for link in page.links():
如果处理 PDF 文档页面,还可能存在注释(Annot)或表单字段(Widget),每个字段都有自己的迭代器:
for annot in page.annots():
for field in page.widgets():
b. 呈现页面 pix 是一个 Pixmap 对象,它(在本例中)包含页面的 RGB 图像,可用于多种用途。
方法 Page.get_pixmap() 提供了许多用于控制图像的变体:分辨率、颜色空间(例如,生成灰度图像或具有减色方案的图像)、透明度、旋转、镜像、移位、剪切等。
例如:创建 RGBA 图像(即,包含 alpha 通道),指定 pix=page.get_pixmap(alpha=True)。
Pixmap 包含以下引用的许多方法和属性。其中包括整数宽度、高度(每个像素)和跨距(一个水平图像行的字节数)。属性示例表示表示图像数据的矩形字节区域(Python 字节对象)。
还可以使用 page.get_svg_image() 创建页面的矢量图像。
c. 将页面图像保存到文件中 pix.save("page-%i.png" % page.number)
d. 提取文本和图像 我们还可以以多种不同的形式和细节级别提取页面的所有文本、图像和其他信息:
text = page.get_text(opt)
"text":(默认)带换行符的纯文本。无格式、无文字位置详细信息、无图像
"blocks":生成文本块(段落)的列表
"words":生成单词列表(不包含空格的字符串)
"html":创建页面的完整视觉版本,包括任何图像。这可以通过 internet 浏览器显示
"dict"/"json":与 HTML 相同的信息级别,但作为 Python 字典或 resp.JSON 字符串。
"rawdict"/"rawjson":"dict"/"json" 的超级集合。它还提供诸如 XML 之类的字符详细信息。
"xhtml":文本信息级别与文本版本相同,但包含图像。
"xml":不包含图像,但包含每个文本字符的完整位置和字体信息。使用 XML 模块进行解释。
e. 搜索文本 areas = page.search_for("mupdf" )
这将提供一个矩形列表,每个矩形都包含一个字符串'mupdf'(不区分大小写)。您可以使用此信息来突出显示这些区域(仅限 PDF)或创建文档的交叉引用。
4. PDF 操作 PDF 是唯一可以使用 PyMuPDF 修改的文档类型。其他文件类型是只读的。
但是,您可以将任何文档(包括图像)转换为 PDF,然后将所有 PyMuPDF 功能应用于转换结果,Document.convert_to_pdf()。
Document.save() 始终将 PDF 以其当前(可能已修改)状态存储在磁盘上。
通常,您可以选择是保存到新文件,还是仅将修改附加到现有文件('增量保存'),这通常要快得多。
4.1 修改、创建、重新排列和删除页面 有几种方法可以操作所谓页面树(描述所有页面的结构):
PDF:Document.delete_page() 和 Document.delete_pages() 删除页面
Document.copy_page()、Document.fullcopy_page() 和 Document.move_page() 将页面复制或移动到同一文档中的其他位置。
Document.select() 将 PDF 压缩到选定页面,参数是要保留的页码序列。这些整数都必须在 0<=i 范围内。执行时,此列表中缺少的所有页面都将被删除。剩余的页面将按顺序出现,次数相同(!)正如您所指定的那样。
第一页或最后 10 页
仅奇数页或偶数页(用于双面打印)
包含或不包含给定文本的页
颠倒页面顺序
保存的新文档将包含仍然有效的链接、注释和书签(i.a.w.指向所选页面或某些外部资源)。
Document.insert_page() 和 Document.new_page() 插入新页面。
此外,页面本身可以通过一系列方法进行修改(例如页面旋转、注释和链接维护、文本和图像插入)。
4.2 连接和拆分 PDF 文档 方法 Document.insert_pdf() 在不同的 pdf 文档之间复制页面。下面是一个简单的 joiner 示例(doc1 和 doc2 在 PDF 中打开):
下面是一个拆分 doc1 的片段。它将创建第一页和最后 10 页的新文档:
doc2 = fitz.open ()
doc2.insert_pdf(doc1, to_page = 9 )
doc2.insert_pdf(doc1, from_page = len (doc1) - 10 )
doc2.save("first-and-last-10.pdf" )
4.3 保存与关闭 Document.save() 将始终以当前状态保存文档。
您可以通过指定选项 incremental=True 将更改写回原始 PDF。这个过程(通常)非常快,因为更改会附加到原始文件,而不会完全重写它。
在程序继续运行时,通常需要'关闭'文档以将底层文件的控制权交给操作系统。
这可以通过 Document.close() 方法实现。除了关闭基础文件外,还将释放与文档关联的缓冲区。
5. 最佳实践与完整示例
5.1 使用上下文管理器 为了自动管理资源,推荐使用上下文管理器来处理文档:
with fitz.open ("example.pdf" ) as doc:
print (f"Pages: {doc.page_count} " )
for page in doc:
text = page.get_text()
print (text[:100 ])
5.2 文本提取深度示例 不同的提取模式适用于不同的场景。以下代码演示了如何根据需求选择提取方式:
import fitz
def extract_text_by_mode (path ):
doc = fitz.open (path)
page = doc[0 ]
plain = page.get_text("text" )
print ("Plain Text:" , plain[:50 ])
blocks = page.get_text("blocks" )
for block in blocks:
x0, y0, x1, y1 = block[:4 ]
text = block[4 ]
print (f"Block at ({x0} , {y0} ): {text[:20 ]} " )
dict_data = page.get_text("dict" )
for block in dict_data["blocks" ]:
if "lines" in block:
for line in block["lines" ]:
for span in line["spans" ]:
print (span["text" ], end="" )
print ()
doc.close()
5.3 常见错误处理 try :
doc = fitz.open ("encrypted.pdf" , password="secret" )
except Exception as e:
print (f"Failed to open: {e} " )
else :
print ("Success" )
doc.close()
通过上述方法,开发者可以高效地利用 PyMuPDF 完成 PDF 文档的解析、提取、修改和转换任务。
相关免费在线工具 curl 转代码 解析常见 curl 参数并生成 fetch、axios、PHP curl 或 Python requests 示例代码。 在线工具,curl 转代码在线工具,online
Base64 字符串编码/解码 将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
Base64 文件转换器 将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online
Markdown转HTML 将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online
HTML转Markdown 将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online
JSON 压缩 通过删除不必要的空白来缩小和压缩JSON。 在线工具,JSON 压缩在线工具,online