news 2026/4/16 19:49:38

Day 44:【99天精通Python】操作 PDF (PyPDF2) - 文档处理的屠龙刀

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Day 44:【99天精通Python】操作 PDF (PyPDF2) - 文档处理的屠龙刀

Day 44:【99天精通Python】操作 PDF (PyPDF2) - 文档处理的屠龙刀

前言

欢迎来到第44天!

在办公自动化领域,除了 Word 和 Excel,PDF是最常见的文件格式。它的特点是"所见即所得",在任何设备上打开格式都不会乱。但这也导致它很难编辑

你是否遇到过这些需求?

  • 把 10 个 PDF 文件合并成一个。
  • 把一个几百页的 PDF拆分成单独的章节。
  • 从 PDF 中提取文本内容(虽然效果不一定完美)。
  • 给 PDF 加密或添加水印。

Python 提供了多个 PDF 处理库,其中最流行、最轻量级的是PyPDF2。今天我们就来掌握这把处理 PDF 的屠龙刀。

本节内容:

  • 安装 PyPDF2
  • 读取 PDF 信息(页数、元数据)
  • 提取文本内容
  • 拆分 PDF 页面
  • 合并多个 PDF
  • 加密与解密 PDF

一、安装 PyPDF2

注意:PyPDF2 在 3.0 版本后 API 有较大变动(如PdfFileReader改名为PdfReader)。本教程使用最新的 3.x 版本。

pipinstallPyPDF2

二、读取 PDF 信息

我们需要一个测试文件sample.pdf

fromPyPDF2importPdfReader# 1. 打开 PDFreader=PdfReader("sample.pdf")# 2. 获取总页数print(f"总页数:{len(reader.pages)}")# 3. 获取元数据 (作者、标题等)meta=reader.metadataprint(f"标题:{meta.title}")print(f"作者:{meta.author}")

2.1 提取文本 (Extract Text)

# 获取第一页page=reader.pages[0]# 提取文本text=page.extract_text()print(text)

注意:PDF 的本质是排版指令,而不是文本流。如果 PDF 是扫描件(全是图片),或者使用了特殊编码的字体,提取出来的可能是乱码或空字符串。对于扫描件,需要使用 OCR 技术(如pytesseract),这超出了 PyPDF2 的能力范围。


三、拆分 PDF (Split)

假设我们要把每一页单独保存为一个 PDF 文件。

fromPyPDF2importPdfReader,PdfWriter reader=PdfReader("sample.pdf")fori,pageinenumerate(reader.pages):# 创建一个写入器writer=PdfWriter()# 将当前页添加到写入器writer.add_page(page)# 保存文件filename=f"page_{i+1}.pdf"withopen(filename,"wb")asf:writer.write(f)print(f"已保存:{filename}")

四、合并 PDF (Merge)

把多个 PDF 合并成一个。PyPDF2 提供了更高级的PdfMerger类,比手动add_page更方便。

fromPyPDF2importPdfMergerimportos# 获取所有要合并的文件files=["report_part1.pdf","report_part2.pdf","report_part3.pdf"]merger=PdfMerger()forpdfinfiles:# append 可以直接追加文件merger.append(pdf)# 保存合并结果merger.write("report_final.pdf")merger.close()print("合并完成!")

进阶:插入到指定位置

# 把 part2 插在 part1 的第 2 页之后merger.append("part1.pdf")merger.merge(2,"part2.pdf")# 在索引2的位置插入

五、加密与解密

5.1 给 PDF 加密码

fromPyPDF2importPdfReader,PdfWriter reader=PdfReader("sample.pdf")writer=PdfWriter()# 将所有页复制到 writerforpageinreader.pages:writer.add_page(page)# 设置密码writer.encrypt("123456")# 保存withopen("locked.pdf","wb")asf:writer.write(f)

5.2 读取加密的 PDF

如果直接读取加密文件,会抛出错误或获取不到内容。

reader=PdfReader("locked.pdf")ifreader.is_encrypted:print("文件已加密,尝试解密...")# 尝试解密 (返回 True/False)ifreader.decrypt("123456"):print(f"解密成功,页数:{len(reader.pages)}")else:print("密码错误!")

六、实战练习:PDF 工具箱

编写一个命令行工具,根据用户输入实现合并或拆分功能。

importosfromPyPDF2importPdfReader,PdfWriter,PdfMergerdefsplit_pdf(filename):"""拆分 PDF 的每一页"""try:reader=PdfReader(filename)base_name=os.path.splitext(filename)[0]fori,pageinenumerate(reader.pages):writer=PdfWriter()writer.add_page(page)output=f"{base_name}_p{i+1}.pdf"withopen(output,"wb")asf:writer.write(f)print(f"拆分完成,共{len(reader.pages)}个文件。")exceptExceptionase:print(f"拆分失败:{e}")defmerge_pdfs(file_list,output_name="merged.pdf"):"""合并多个 PDF"""merger=PdfMerger()try:forpdfinfile_list:ifos.path.exists(pdf):merger.append(pdf)else:print(f"跳过不存在的文件:{pdf}")merger.write(output_name)print(f"合并完成:{output_name}")exceptExceptionase:print(f"合并失败:{e}")finally:merger.close()if__name__=="__main__":print("1. 拆分 PDF")print("2. 合并 PDF")choice=input("请选择: ")ifchoice=="1":path=input("请输入要拆分的 PDF 路径: ")split_pdf(path)elifchoice=="2":paths=input("请输入要合并的 PDF 路径 (用逗号分隔): ").split(",")# 去除空白paths=[p.strip()forpinpaths]merge_pdfs(paths)

七、常见问题

Q1:提取的文本是乱码?

这通常是因为 PDF 缺少字体映射表(CMap),或者是图片型 PDF。
解决方案:PyPDF2 搞不定。尝试pdfplumber库(提取效果更好),或者pytesseract(OCR 识别)。

Q2:合并后文件体积变大?

PDF 内部可能包含重复的字体或图片资源。合并时 PyPDF2 有时无法完美去重。可以使用 Acrobat Pro 进行优化,或者尝试pikepdf库。

Q3:如何旋转页面?

# 顺时针旋转 90 度page.rotate(90)

八、小结

PyPDF2

读取 PdfReader

写入 PdfWriter

合并 PdfMerger

len(pages) 页数

pages[0].extract_text() 文本

decrypt() 解密

add_page() 添加页

encrypt() 加密

write() 保存

append() 追加文件

merge() 插入文件

关键要点

  1. 拆分Reader读,Writer写。
  2. 合并:直接用PdfMerger最快。
  3. 局限性:对文本提取支持有限,不适合处理扫描件。

九、课后作业

  1. 奇偶拆分:编写程序,将一个 PDF 拆分成两个文件:odd.pdf(包含第 1,3,5… 页)和even.pdf(包含第 2,4,6… 页)。
  2. 页面旋转矫正:读取一个 PDF,将所有页面旋转 180 度(倒立),并保存为新文件。
  3. 水印添加 (挑战):结合 Day 42 (Pillow) 和 PyPDF2。先用 Pillow 生成一张透明的水印图片,转为 PDF,然后将水印 PDF 与目标 PDF 的每一页进行合并(Overlay)。(提示:page.merge_page())。

下节预告

Day 45:进阶篇总结与展望- 我们的进阶之旅即将画上句号。明天我们将复盘进阶篇的核心知识体系,并为接下来的重头戏——实战篇 (数据分析与Web开发)做好准备!


系列导航

  • 上一篇:Day 43 - 发送邮件smtplib
  • 下一篇:Day 45 - 进阶篇总结与展望(待更新)
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/16 9:08:28

Day 49:【99天精通Python】Pandas 进阶 - 数据清洗与合并

Day 49:【99天精通Python】Pandas 进阶 - 数据清洗与合并 前言 欢迎来到第49天! 在现实世界中,我们拿到的数据从来都不是完美的。它们可能: 缺胳膊少腿:某些单元格是空的 (NaN)。脏乱差:格式不统一&#xf…

作者头像 李华
网站建设 2026/4/16 16:11:33

教育评估自动化:PDF-Extract-Kit在学生作业分析应用

教育评估自动化:PDF-Extract-Kit在学生作业分析应用 随着教育数字化进程的加速,教师面临大量纸质或PDF格式的学生作业批改任务。传统人工评阅不仅耗时耗力,且难以实现结构化数据留存与横向对比分析。在此背景下,自动化文档内容提…

作者头像 李华
网站建设 2026/4/16 13:02:54

亲测Z-Image-Turbo_UI界面,输入提示词秒出高质量图片

亲测Z-Image-Turbo_UI界面,输入提示词秒出高质量图片 1. 引言:从命令行到图形化——AI图像生成的体验升级 在当前文本到图像模型快速发展的背景下,Z-Image-Turbo 凭借其出色的生成质量和极快的推理速度(仅需8步即可输出高清图像…

作者头像 李华
网站建设 2026/4/15 13:15:55

Qwen3-VL-30B新手指南:没GPU也能玩转多模态AI

Qwen3-VL-30B新手指南:没GPU也能玩转多模态AI 你是不是也和我一样,对AI图像理解特别感兴趣?看到别人用大模型分析照片、识别文档、甚至看图写文案,心里痒痒的。但一搜教程,满屏都是“安装CUDA”“配置PyTorch”“显存…

作者头像 李华
网站建设 2026/4/16 11:10:32

FRCRN语音降噪模型部署案例:4090D显卡性能调优技巧

FRCRN语音降噪模型部署案例:4090D显卡性能调优技巧 1. 技术背景与应用场景 随着智能语音设备的普及,语音信号在真实环境中的质量受到噪声干扰的问题日益突出。尤其在单麦克风场景下,缺乏空间信息支持,对降噪算法提出了更高要求。…

作者头像 李华
网站建设 2026/4/16 11:07:46

高效中文逆文本标准化|基于FST ITN-ZH镜像一键转换

高效中文逆文本标准化|基于FST ITN-ZH镜像一键转换 在语音识别、自然语言处理和智能客服等实际应用中,系统输出的原始文本往往包含大量口语化表达。例如,“二零零八年八月八日”、“早上八点半”或“一百二十三”,这些表述虽然人…

作者头像 李华