基于特定文本匹配的Python多页PDF拆分需求及代码报错排查
修正后的PyPDF2 PDF拆分代码及错误说明
原代码中的关键错误
- 未导入
PageObject且调用方式错误:应该使用当前页面对象的extract_text()方法,而非PageObject.extract_text() - 变量作用域问题:保存文件时的
municipality未在当前作用域定义,且原逻辑未关联页码与对应城市名称 - 未导入
Path模块,导致文件路径拼接失败 - 拆分逻辑错误:原循环条件会多包含一页,且未处理最后一段无标记的内容
- 重复初始化
PdfReader:函数内和外部都打开了同一个PDF,浪费资源
修正后的完整代码
from PyPDF2 import PdfWriter, PdfReader import re from pathlib import Path # 替换为你的实际城市列表 array_merged_zone_send = ["rome", "milan", "naples"] def get_page_breaks(file_name: str) -> list[tuple[int, str]]: pdf_reader = PdfReader(file_name) page_breaks = [] for page_num in range(len(pdf_reader.pages)): page = pdf_reader.pages[page_num] page_text = page.extract_text() if not page_text: continue # 跳过无文本页面 for municipality in array_merged_zone_send: target_text = f'PANORAMICA DI {municipality.upper()}' if re.search(target_text, page_text): page_breaks.append((page_num, municipality)) break # 找到匹配后跳出循环,避免重复记录 return page_breaks def split_pdf(input_path: str, page_breaks: list[tuple[int, str]]): pdf_reader = PdfReader(input_path) total_pages = len(pdf_reader.pages) # 添加文档末尾作为最后一个分割点 page_breaks.append((total_pages, None)) for idx in range(len(page_breaks)-1): start_page, municipality = page_breaks[idx] end_page, _ = page_breaks[idx+1] # 子PDF包含从start_page到end_page-1的页面 writer = PdfWriter() for page_num in range(start_page, end_page): writer.add_page(pdf_reader.pages[page_num]) # 生成目标文件并保存 output_filename = f'zp_{municipality}.pdf' with open(Path('.') / output_filename, "wb") as out_stream: writer.write(out_stream) print(f"已生成文件: {output_filename}") # 主执行逻辑 if __name__ == "__main__": input_pdf_path = "./report1.pdf" breaks = get_page_breaks(input_pdf_path) if not breaks: print("未找到任何匹配的标记文本,无法拆分PDF") else: split_pdf(input_pdf_path, breaks)
关键改进说明
- 将页码与对应城市名称绑定存储,确保生成的文件名准确对应目标内容
- 优化文本提取逻辑,跳过无文本页面提升效率
- 拆分逻辑更清晰:从当前标记页开始,到下一个标记页的前一页结束
- 统一管理PDF阅读器实例,避免重复打开文件浪费资源
- 添加基础错误处理:未找到标记时给出明确提示
- 使用
pathlib处理文件路径,跨系统兼容性更好
内容的提问来源于stack exchange,提问作者simone100
相关产品推荐
相关产品推荐

