You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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脚本实现全流程。


解决方案

首先修正现有代码的三处基础笔误:

  1. 模块导入关键字import为小写,原代码开头写的大写Import会触发语法错误
  2. 正则编译方法为re.compile,原代码写的re.compiler不存在
  3. glob匹配文件夹下所有PDF需要加通配符,正确路径格式为目标文件夹路径/*.pdf,否则无法匹配到文件

实现思路

  1. 逐行遍历读取到的Excel数据,过滤空单元格,为每一行生成独立的关键词列表,行号和Excel实际行号对齐方便排查
  2. 提前遍历所有PDF文件,一次性提取全文本缓存到字典中,避免每次校验行数据都重复读取PDF,提升运行效率
  3. 对每一行的关键词列表,遍历缓存的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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 13:45:31