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

多PDF文件表格重复姓名提取问题及pdfminer代码调试

问题分析与修复方案

你的代码存在几个关键问题导致无法得到预期结果,下面逐一说明并给出修正后的代码:

核心问题点

  • 导入语句位置错误:把pdfminer的导入放在循环内部,每次处理文件都会重复导入模块,完全没必要,还会降低效率。
  • 姓名提取逻辑不完整:需求是提取"name surname"列的完整姓名,但原代码只取了"name"后的第一个单词,漏掉了姓氏部分。
  • 缺乏跨文件的姓名统计机制:只是把所有找到的姓名塞进同一个列表,无法区分每个姓名出现在哪些文件里,也就没法筛选出在2个及以上文件中出现的重复项。
  • 未处理非文本布局元素:当布局元素不是LTTextBox或LTTextLine时,parole变量可能未被定义就被使用,会引发NameError。
  • 未检查文本提取权限:没有验证PDF是否允许文本提取,遇到加密或禁止提取的文件会直接报错。

修复后的代码

from pdfminer.pdfparser import PDFParser
from pdfminer.pdfdocument import PDFDocument
from pdfminer.pdfpage import PDFPage
from pdfminer.pdfpage import PDFTextExtractionNotAllowed
from pdfminer.pdfinterp import PDFResourceManager
from pdfminer.pdfinterp import PDFPageInterpreter
from pdfminer.layout import LAParams, LTTextBox, LTTextLine
from pdfminer.converter import PDFPageAggregator
from collections import defaultdict

# 用字典存储每个姓名出现的文件集合
name_file_map = defaultdict(set)
pdf_files = ['documento1.pdf', 'documento2.pdf']

for idx, file_path in enumerate(pdf_files):
    with open(file_path, 'rb') as file:
        parser = PDFParser(file)
        document = PDFDocument(parser)
        
        # 检查是否允许文本提取
        if not document.is_extractable:
            raise PDFTextExtractionNotAllowed(f"文件 {file_path} 禁止文本提取")
        
        rsrcmgr = PDFResourceManager()
        laparams = LAParams()
        device = PDFPageAggregator(rsrcmgr, laparams=laparams)
        interpreter = PDFPageInterpreter(rsrcmgr, device)
        
        for page in PDFPage.create_pages(document):
            interpreter.process_page(page)
            layout = device.get_result()
            
            for element in layout:
                # 只处理文本元素
                if isinstance(element, (LTTextBox, LTTextLine)):
                    text = element.get_text().strip()
                    if not text:
                        continue
                    parole = text.split()
                    
                    # 遍历寻找"name"关键词,提取后续的姓名(名+姓)
                    for indice, parola in enumerate(parole):
                        # 确保有足够的后续单词提取完整姓名,且"name"是表头
                        if parola.lower() == 'name' and indice + 2 <= len(parole):
                            full_name = f"{parole[indice+1]} {parole[indice+2]}"
                            # 记录该姓名出现在当前文件中
                            name_file_map[full_name].add(file_path)

# 筛选出在2个及以上文件中出现的姓名
duplicate_names = [name for name, files in name_file_map.items() if len(files) >= 2]

print("在2个及以上文件中出现的重复姓名:")
for name in duplicate_names:
    print(name)

代码说明

  1. 模块导入优化:把所有导入语句移到代码顶部,符合Python编码规范。
  2. 姓名提取逻辑修正:假设"name"后面紧跟的是名和姓(两个单词),提取并拼接成完整姓名;同时增加lower()处理,避免大小写问题(比如表头是"Name"而不是"name")。
  3. 跨文件统计机制:使用defaultdict(set)存储每个姓名对应的文件集合,这样可以清晰看到每个姓名出现在哪些文件中。
  4. 异常与边界处理:
    • 检查PDF是否允许文本提取,提前抛出明确错误。
    • 跳过空文本元素,避免处理无效内容。
    • 增加索引判断,确保提取姓名时不会超出列表范围。
  5. 结果筛选:最后通过判断姓名对应的文件集合大小,筛选出出现次数≥2的重复姓名。

内容的提问来源于stack exchange,提问作者Ryu10

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 05:05:40