如何使用Python提取PDF指定页码范围并拆分保存为独立文件?
我看了你的代码,发现几个关键问题导致它没法正确按需求拆分PDF——你应该是想按包含Challenge 1:和Challenge 2:的标记来拆分文档,提取中间的名称作为每个拆分文件的文件名对吧?咱们一步步来修正:
先说说原代码里的核心问题
- 循环里每次都新建
PdfFileWriter,还误用了未定义的page_num、page变量,根本没法正确添加页面 - 提取
loanAcctName的逻辑太生硬,只要页面里找不到其中一个关键词,直接就会报错 pageList的添加逻辑完全重复,不管有没有匹配关键词都加,完全起不到筛选作用- 你定义了
directory但根本没用到,拆分的文件会存在脚本当前目录,不是你指定的路径 - 手动调用
out.close()完全多余,with语句会自动帮你关闭文件 - 用
object当变量名是踩了Python内置关键字的坑,容易出奇怪的问题
修正后的代码
import os from PyPDF2 import PdfFileReader, PdfFileWriter import re def pdf_splitter(pdf_path): # 定义输出目录,确保目录存在(如果不存在就创建) directory = "C:\\Users\\Docs\\" os.makedirs(directory, exist_ok=True) fname = os.path.splitext(os.path.basename(pdf_path))[0] print(f"处理文件: {fname}") # 避免用Python内置关键字当变量名,改用pdf_reader pdf_reader = PdfFileReader(pdf_path) total_pages = pdf_reader.getNumPages() print(f"总页数: {total_pages}") # 定义要匹配的关键词 challenge1_str = "Challenge 1:" challenge2_str = "Challenge 2:" # 记录当前正在处理的挑战的页码和名称 current_challenge_pages = [] current_loan_name = None for page_idx in range(total_pages): page = pdf_reader.getPage(page_idx) page_text = page.extractText() # 遇到Challenge 1:时,先保存上一个未完成的挑战(如果有的话) if re.search(challenge1_str, page_text): if current_challenge_pages and current_loan_name: save_challenge_pdf(pdf_reader, current_challenge_pages, current_loan_name, directory) current_challenge_pages = [] # 提取两个关键词之间的名称,处理找不到Challenge 2:的情况 start_idx = page_text.find(challenge1_str) + len(challenge1_str) end_idx = page_text.find(challenge2_str) if end_idx != -1: current_loan_name = page_text[start_idx:end_idx].strip() else: # 如果当前页面没有Challenge 2:,用默认名称避免报错 current_loan_name = f"{fname}_Challenge_{len(current_challenge_pages)+1}" # 如果当前有正在处理的挑战,把当前页面加入列表 if current_loan_name is not None: current_challenge_pages.append(page_idx) # 处理最后一个挑战的内容(循环结束后可能还有未保存的) if current_challenge_pages and current_loan_name: save_challenge_pdf(pdf_reader, current_challenge_pages, current_loan_name, directory) def save_challenge_pdf(pdf_reader, page_indices, loan_name, output_dir): """把指定页码范围保存为单独的PDF文件的辅助函数""" pdf_writer = PdfFileWriter() for idx in page_indices: pdf_writer.addPage(pdf_reader.getPage(idx)) # 清理文件名里的非法字符,避免保存失败 clean_loan_name = re.sub(r'[<>:"/\\|?*]', '', loan_name) output_filename = f"{clean_loan_name}.pdf" output_path = os.path.join(output_dir, output_filename) with open(output_path, 'wb') as out_file: pdf_writer.write(out_file) print(f"已创建: {output_path}") if __name__ == '__main__': pdf_path = r"C:\\Users\\FY22.pdf" pdf_splitter(pdf_path)
修正点说明
- 新增了
save_challenge_pdf辅助函数,把保存PDF的逻辑抽出来,代码更清晰易维护 - 自动创建输出目录,避免因为目录不存在导致保存失败
- 处理了关键词找不到的边界情况,不会因为页面没包含
Challenge 2:就报错 - 清理文件名里的非法字符(比如冒号、斜杠这些),避免Windows系统下保存失败
- 正确按
Challenge 1:的标记拆分文档,把每个挑战对应的所有页面保存为一个独立文件 - 移除了原代码里无用的逻辑,优化了变量命名,避免踩Python关键字的坑
内容的提问来源于stack exchange,提问作者Amit Sharma
相关产品推荐
相关产品推荐

