Python实现多PDF匹配Excel多行关键词全量校验方案求助
PDF交易信息校验脚本实现方案
问题背景
我是Python初学者,在开发业务校验脚本过程中遇到问题,特来求助。本次开发目标为校验指定必填信息(即关键词)是否存在于对应PDF文件中:现有一份Excel文件,每行对应一笔交易记录,需校验当日收到的对应PDF文件中,是否包含每笔交易及其关联的所有必填信息。
具体场景如下:Excel工作表的多行存储了每笔交易对应的必填信息,另有一个文件夹存放当日所有待校验PDF文件。我尝试提取每个PDF的文本内容,校验Excel每行对应的信息是否完整存在于某一个PDF中,参考了社区相关解决方案但尚未实现完整可用的功能。
现有代码
目前已完成PDF内容提取、关键词检索部分的代码编写:
Import os from glob import glob import re from PyPDF2 import PdfFileReader def search_page(pattern, page): yield from pattern.findall(page.extractText()) def search_document(pattern, path): document = PdfFileReader(path) for page in document.pages: yield from search_page(pattern, page) searchWords = ['my list of keywords in each row of my Excel file'] pattern = re.compiler(r'\b(?:%s)\b' % '|'.join(searchWords)) for path in glob('path of my folder with all the pdf files'): matches = search_document(pattern, path)
上述代码参考Stack Overflow上用于统计关键词出现次数的方案编写
目前已知可以用pandas读取Excel指定列,但无法将读取到的内容接入检索逻辑(现有检索逻辑接收字符串输入而非逐行的关键词列表),Excel读取代码如下:
import pandas as pd df=pd.read_excel('path of my Excel file', sheet_name=0, usecols='G,L,R,S,Z') print(df) # 校验是否选中正确列,过滤其他无关列的冗余信息
待解决问题
- 如何为Excel每一行生成对应的检索关键词列表,并接入前述PDF检索代码逻辑
- 如何实现全词匹配校验逻辑:要求某一行的所有关键词必须全部存在于同一个PDF中(即同一笔交易的所有信息必须归集在同一个PDF内)
- 如何输出校验结果:某行全部关键词匹配成功则返回类似“第X行校验通过”的提示,匹配失败则返回错误提示,逐行完成所有交易记录的校验
补充说明:最初计划仅通过Python提取数据后接入Alteryx工作流,但公司环境下Alteryx的Python工具不支持部分所需依赖包,因此需要独立的Python脚本实现全流程。
解决方案
首先修正现有代码的三处基础笔误:
- 模块导入关键字
import为小写,原代码开头写的大写Import会触发语法错误 - 正则编译方法为
re.compile,原代码写的re.compiler不存在 glob匹配文件夹下所有PDF需要加通配符,正确路径格式为目标文件夹路径/*.pdf,否则无法匹配到文件
实现思路
- 逐行遍历读取到的Excel数据,过滤空单元格,为每一行生成独立的关键词列表,行号和Excel实际行号对齐方便排查
- 提前遍历所有PDF文件,一次性提取全文本缓存到字典中,避免每次校验行数据都重复读取PDF,提升运行效率
- 对每一行的关键词列表,遍历缓存的PDF文本,只要找到某一个PDF包含该行全部关键词即判定校验通过,否则判定失败,同时输出缺失的关键词方便定位问题
完整可运行代码
import os from glob import glob import re import pandas as pd from PyPDF2 import PdfFileReader # 配置项 - 修改为实际本地路径 EXCEL_PATH = "你的交易Excel文件完整路径.xlsx" PDF_FOLDER_GLOB = "存放待校验PDF的文件夹路径/*.pdf" IGNORE_CASE = True # 匹配时是否忽略大小写 HAS_EXCEL_HEADER = True # Excel是否有表头,有表头则行号从2开始计数 def extract_pdf_text(pdf_path): """提取单个PDF的全部文本内容""" full_text = "" reader = PdfFileReader(pdf_path, strict=False) for page in reader.pages: page_text = page.extractText() if page_text: full_text += page_text + "\n" return full_text def is_all_keywords_matched(keywords, text): """检查文本中是否全词匹配所有关键词""" flag = re.IGNORECASE if IGNORE_CASE else 0 for kw in keywords: kw_clean = kw.strip() if not kw_clean: continue # 转义关键词中的正则特殊字符,避免匹配异常 kw_pattern = re.compile(rf"\b{re.escape(kw_clean)}\b", flag) # *中文关键词适配:如果关键词包含中文,\b边界不生效,可替换为下面的直接包含判断 # if kw_clean not in text: if not kw_pattern.search(text): return False return True if __name__ == "__main__": # 1. 读取Excel,生成逐行关键词映射 df = pd.read_excel(EXCEL_PATH, sheet_name=0, usecols='G,L,R,S,Z') row_keywords = {} for df_idx, row in df.iterrows(): excel_row_num = df_idx + 2 if HAS_EXCEL_HEADER else df_idx + 1 kw_list = [] for cell in row: if pd.notna(cell): cell_str = str(cell).strip() if cell_str: kw_list.append(cell_str) if kw_list: row_keywords[excel_row_num] = kw_list # 2. 预加载所有PDF文本 pdf_cache = {} for pdf_path in glob(PDF_FOLDER_GLOB): try: pdf_text = extract_pdf_text(pdf_path) pdf_cache[os.path.basename(pdf_path)] = pdf_text print(f"已加载PDF:{os.path.basename(pdf_path)}") except Exception as e: print(f"加载PDF失败 {os.path.basename(pdf_path)},错误:{str(e)}") # 3. 逐行校验输出结果 print("\n" + "="*20 + " 开始校验 " + "="*20) pass_num = 0 fail_num = 0 for row_num, kws in row_keywords.items(): matched_pdf = "" for pdf_name, pdf_text in pdf_cache.items(): if is_all_keywords_matched(kws, pdf_text): matched_pdf = pdf_name break if matched_pdf: print(f"第{row_num}行校验通过,匹配文件:{matched_pdf}") pass_num += 1 else: # 统计缺失关键词 missing = [] for kw in kws: kw_clean = kw.strip() exist = False for pdf_text in pdf_cache.values(): flag = re.IGNORECASE if IGNORE_CASE else 0 if re.search(rf"\b{re.escape(kw_clean)}\b", pdf_text, flag): exist = True break if not exist: missing.append(kw_clean) print(f"第{row_num}行校验失败,未找到包含全部关键词的PDF,缺失关键词:{', '.join(missing)}") fail_num += 1 print(f"\n校验完成:共{pass_num}条记录通过,{fail_num}条记录失败")
补充说明
- 如果关键词包含中文,正则的
\b单词边界规则无法正确识别中文词边界,把is_all_keywords_matched函数里的正则判断替换为注释里的直接包含判断即可 - 如果PyPDF2对部分格式复杂的PDF提取文本效果差,可以替换为
pdfplumber库,提取文本的逻辑基本一致,识别准确率更高 - 脚本默认输出校验失败行缺失的关键词,不需要可以自行删除对应逻辑
内容的提问来源于stack exchange,提问作者Doc blue
相关产品推荐
相关产品推荐

