前阵子我在家里写脚本,帮我老妈处理她工作上的一大堆文件。在做文档自动化转换的时候,我再次深刻体会到:在所有办公文档里,PDF绝对是最让人头疼的一个。
它不像Excel那样可以直接读取单元格,也不像Word那样结构清晰。想要用代码搞定PDF的文字提取、图片抓取甚至页面合并,如果没有趁手的工具,简直就是一场灾难。
请在微信客户端打开
当时我尝试了好几个主流的库,最后还是回到了 PyMuPDF 的怀抱。说实话,在Python的PDF处理圈子里,如果PyMuPDF排第二,真的很难找出一个能稳拿第一的。它不仅运行速度极快,而且底层基于强大的MuPDF引擎,不管是提取文本、操作图像还是渲染页面,都稳得不可思议。
今天这篇文章,我就带大家把这个库摸透。没有长篇大论的理论,我们直接用流程和代码说话。
整体处理流程
在开始敲代码之前,我们先在脑海里建立一个简单的处理模型。无论你是要提取数据还是修改文件,使用 PyMuPDF 的基本逻辑都非常固定:
graph TDA[开始运行] --> B[导入 fitz 模块]B --> C[打开并读取目标PDF文件]C --> D{你需要做什么操作?}D -->|提取文字| E[遍历页面对象提取 Text]D -->|提取图片| F[分析页面的 Image 列表]D -->|合并拆分| G[操作 Document 对象增删页面]D -->|加盖水印| H[在页面插入 Text 或图像]E --> I[保存处理结果]F --> IG --> IH --> II --> J[关闭文件,释放内存]
(顺便提一句,虽然这个库叫 PyMuPDF,但在代码里导入的时候,它的名字叫 fitz,这点很容易让新手踩坑,一定要记住。)
核心功能实战代码
废话不多说,我们直接看在实际业务中最常用的几个功能是怎么用代码实现的。准备好你的编辑器,如果你还没有安装,先在终端跑一下
pip install PyMuPDF。场景一:一键提取文档里的所有纯文本
这是最常见的需求。比如老板丢给你几十个行业报告的PDF,让你把里面的关键数据找出来。如果手动复制粘贴,一天就过去了。用代码只需要几行:
import fitz # 记得导入的是 fitzdef extract_text_from_pdf(pdf_path):# 打开PDF文件doc = fitz.open(pdf_path)full_text = ""# 遍历每一页for page_num in range(doc.page_count):page = doc.load_page(page_num)# 提取当前页面的文本text = page.get_text()full_text += f"\n--- 第 {page_num + 1} 页 ---\n"full_text += text# 记得关闭文件释放资源doc.close()return full_text# 测试一下my_pdf = "sample_report.pdf"print(extract_text_from_pdf(my_pdf))
场景二:把PDF里的插图全部“抠”出来
有时候我们需要的不是文字,而是PDF报告里的高清配图。PyMuPDF 可以直接读取到文档底层的图像对象,并把它们还原成独立的图片文件。
import fitzimport osdef extract_images(pdf_path, output_folder):if not os.path.exists(output_folder):os.makedirs(output_folder)doc = fitz.open(pdf_path)image_count = 0for page_num in range(len(doc)):page = doc[page_num]# 获取当前页面的所有图像列表image_list = page.get_images(full=True)for img_index, img in enumerate(image_list):xref = img[0] # 获取图片的交叉引用号# 提取图像的原始字节数据base_image = doc.extract_image(xref)image_bytes = base_image["image"]image_ext = base_image["ext"] # 获取图片格式,如png, jpeg# 拼接保存路径并写入文件image_filename = f"page{page_num+1}_img{img_index+1}.{image_ext}"image_filepath = os.path.join(output_folder, image_filename)with open(image_filepath, "wb") as f:f.write(image_bytes)image_count += 1doc.close()print(f"提取完成!共搞定 {image_count} 张图片,保存在 {output_folder} 文件夹中。")
场景三:多个PDF文件无缝合并
月底整理发票或者汇总多个部门的报告时,这个脚本极其好用。它可以把多个PDF文件按顺序拼接成一个完整的文件。
import fitzdef merge_pdfs(pdf_list, output_path):# 创建一个新的空白PDF文档result_doc = fitz.open()for pdf in pdf_list:# 打开需要合并的子文件with fitz.open(pdf) as doc:# 将当前文档的所有页面插入到结果文档的末尾result_doc.insert_pdf(doc)# 保存最终文件result_doc.save(output_path)result_doc.close()print(f"合并成功!文件已保存为: {output_path}")# 假设我们有三个文件需要合并files_to_merge = ["part1.pdf", "part2.pdf", "part3.pdf"]merge_pdfs(files_to_merge, "final_merged_report.pdf")
场景四:给重要文档批量打上水印
发给客户的文件怕被随意盗用?我们可以用脚本批量给每一页的中间加上半透明的文字水印,省去了用商业软件一个个加的麻烦。
import fitzdef add_watermark(pdf_path, watermark_text, output_path):doc = fitz.open(pdf_path)for page in doc:# 获取页面的矩形范围rect = page.rect# 计算水印插入的位置(大致放在页面中央)point = fitz.Point(rect.width / 4, rect.height / 2)# 插入文本水印# 可以自定义字体大小、颜色和旋转角度page.insert_text(point,watermark_text,fontsize=45,color=(0.7, 0.7, 0.7), # 灰色rotate=45 # 倾斜45度)doc.save(output_path)doc.close()print("水印添加完毕!")add_watermark("contract.pdf", "机密文件-严禁外传", "contract_watermarked.pdf")
写在最后
Python能做的事情真的很多,而 PyMuPDF 就是我们在处理文档时最锋利的那把瑞士军刀。上面这些代码,大家可以直接复制到自己的电脑上运行试试。只要稍微修改一下路径,就能马上应用到你每天的工作中。
少做点无聊的重复劳动,把时间留给更有价值的事情,或者早点下班回家休息,这才是我们学习代码的真正意义。
如果你觉得今天的分享对你有帮助,不妨点个在看或者分享给身边被文档折磨的同事。我们下期再见!

夜雨聆风