PyMuPDF提取多PDF数据至CSV仅获首页内容问题排查
解决多页PDF信息提取不全的问题
问题根源分析
你的代码出现提取不全的问题,核心原因有两点:
- 正则表达式重复/匹配失效:
R_P_pattern和R_T_pattern完全一致,会导致两者匹配同一内容甚至互相干扰;同时PDF文本常存在换行,你的正则默认不支持跨行匹配,导致后续页面的目标文本被换行打断后无法命中。 - 缺少调试反馈:无法直观看到每个页面的匹配情况,难以定位是页面文本加载失败,还是正则规则不匹配。
解决方案步骤
- 修正重复正则:为
R_P和R_T编写独立的正则规则,精准匹配各自的目标字段。 - 添加跨行匹配标志:给所有正则匹配添加
re.DOTALL(让.匹配换行符)和re.UNICODE(处理特殊字符),适配PDF文本的换行场景。 - 增加调试输出:在页面循环中打印匹配结果,快速定位未命中的字段和对应页面。
修正后的代码
import os import csv import re import fitz # 修正正则:区分R_P和R_T的匹配规则(需根据实际PDF文本调整) I_T_Pattern = r'Lorem ipsum dolor sit amet (\w+ \d{1,2}, \d{4}) \(Lorem ipsum dolor sit amet\)' # 示例:假设R_P的文本末尾带有特定标识 R_P_pattern = r'Lorem ipsum dolor sit amet (\d+) Lorem ipsum dolor sit amet - RP' # 示例:假设R_T的文本开头带有特定标识 R_T_pattern = r'RT - Lorem ipsum dolor sit amet (\d+) Lorem ipsum dolor sit amet' NON_R_pattern = r'Lorem ipsum dolor sit amet (\d+)' E_D_pattern = r'Lorem ipsum dolor sit amet \(“Lorem ipsum dolor sit amet”\), Lorem ipsum dolor sit amet (\w+ \d{1,2}, \d{4})' L_pattern = r'“Lorem ipsum dolor sit amet”\)\.(\s+)(\w+[\s\w]*),' def extract_contract_data(pdf_file): doc = fitz.open(pdf_file) I_T = None R_P = None R_T = None NON_R = None E_D = None L = None for page_num in range(doc.page_count): page = doc.load_page(page_num) text = page.get_text() # 调试用:打印当前页面文本(可根据需求注释) # print(f"\n--- 第 {page_num+1} 页文本 ---") # print(text) # 启用跨行匹配,适配PDF文本换行 I_T_match = re.search(I_T_Pattern, text, re.DOTALL | re.UNICODE) R_P_match = re.search(R_P_pattern, text, re.DOTALL | re.UNICODE) R_T_match = re.search(R_T_pattern, text, re.DOTALL | re.UNICODE) NON_R_match = re.search(NON_R_pattern, text, re.DOTALL | re.UNICODE) E_D_match = re.search(E_D_pattern, text, re.DOTALL | re.UNICODE) L_match = re.search(L_pattern, text, re.DOTALL | re.UNICODE) # 调试用:打印当前页面各字段匹配结果 print(f"第 {page_num+1} 页匹配结果:") print(f"I_T: {I_T_match.group(1) if I_T_match else '未找到'}") print(f"R_P: {R_P_match.group(1) if R_P_match else '未找到'}") print(f"R_T: {R_T_match.group(1) if R_T_match else '未找到'}") print(f"NON_R: {NON_R_match.group(1) if NON_R_match else '未找到'}") print(f"E_D: {E_D_match.group(1) if E_D_match else '未找到'}") print(f"L: {L_match.group(2) if L_match else '未找到'}") # 仅在字段未赋值时更新 if I_T_match and not I_T: I_T = I_T_match.group(1) if R_P_match and not R_P: R_P = R_P_match.group(1) if R_T_match and not R_T: R_T = R_T_match.group(1) if NON_R_match and not NON_R: NON_R = NON_R_match.group(1) if E_D_match and not E_D: E_D = E_D_match.group(1) if L_match and not L: L = L_match.group(2) doc.close() return { "L": L, "E D": E_D, "I T": I_T, "R P": R_P, "R T": R_T, "NON R": NON_R } def main(): pdf_dir = r'C:\\path' pdf_files = [os.path.join(pdf_dir, f) for f in os.listdir(pdf_dir) if f.endswith(".pdf")] data = [] for pdf_file in pdf_files: print(f"\n=== 处理文件:{os.path.basename(pdf_file)} ===") contract_data = extract_contract_data(pdf_file) data.append(contract_data) output_file = r'C:\\output.csv' with open(output_file, "w", newline='', encoding='utf-8') as file: fieldnames = ["L", "E D", "I T", "R P", "R T", "NON R"] writer = csv.DictWriter(file, fieldnames=fieldnames) writer.writeheader() writer.writerows(data) print(f"\n结果已保存至:{output_file}") if __name__ == "__main__": main()
额外注意事项
- 你需要根据实际PDF中的文本内容,调整
R_P_pattern和R_T_pattern的具体规则,确保它们能分别匹配到对应页面的目标字段。 - 如果调试发现某些页面文本提取不全,可能是PDF为扫描件格式(fitz无法提取文本),这种情况需要配合OCR工具(如pytesseract)处理。
内容的提问来源于stack exchange,提问作者J D
相关产品推荐
相关产品推荐

