如何使用Python NLP从PDF文本中提取指定关键词对应的数值?
基于spaCy的PDF关键词关联数值提取实现方案
方案可行性说明
你初步设想的技术路径完全可行,10份PDF的量级下不需要担心效率问题,哪怕单份文件页数超过100页,整套流程跑下来总耗时也不会超过1分钟,远高于手动操作的效率。
分步实现逻辑
- 第一步:PDF文本提取与清洗
优先选用pymupdf(fitz)库完成PDF文本提取,比PyPDF2、pdfminer的文本识别准确率更高,能更好保留数值与关键词的相邻位置关系。清洗阶段仅需去除多余换行、冗余空格、重复的页眉页脚内容即可,不要做过多文本归一化操作,避免破坏数值与关键词的关联结构。 - 第二步:spaCy规则匹配设计
不用手动做全文遍历匹配,直接调用spaCy的Matcher组件,将「数值+关键词」「关键词+数值」的相邻关联写进匹配规则,可直接同时捞出关联的关键词和对应数值,不需要额外做位置判断:
匹配规则覆盖两种常见的文本结构即可满足绝大多数场景需求:- 数值(支持带千位分隔符的格式)+ 空格 + 目标关键词
- 目标关键词 + 冒号/空格 + 数值
spaCy自带NUM词性标注能力,不需要自己写正则识别数值,千位分隔符格式的数字也能被准确识别为数值类型。
- 第三步:结果整理输出
匹配到的结果按「PDF文件名、匹配关键词、对应数值、匹配上下文」四个字段存储到pandas DataFrame中,可直接导出为Excel或CSV文件,可增加去重逻辑避免同一内容被多次匹配统计。
注意:上述方案仅适用于可复制文本的原生PDF,如果是扫描件格式的PDF,需要先增加OCR识别步骤,用pytesseract将图片内容转为文本后再执行后续操作
核心参考代码
import spacy from spacy.matcher import Matcher import fitz import pandas as pd # 加载spaCy英文基础模型,小型模型即可满足需求 nlp = spacy.load("en_core_web_sm") matcher = Matcher(nlp.vocab) # 自定义目标关键词列表 TARGET_KEYWORDS = ["Metric Tonnes", "Volume", "Climate Change"] # 写入匹配规则 for keyword in TARGET_KEYWORDS: # 拆分关键词为单个token,不区分大小写匹配 keyword_tokens = [{"LOWER": token.lower()} for token in keyword.split()] # 规则1:数值在前,关键词紧随其后 pattern1 = [{"POS": "NUM"}] + keyword_tokens # 规则2:关键词在前,中间可带标点/空格,后接数值 pattern2 = keyword_tokens + [{"POS": "PUNCT", "OP": "?"}, {"POS": "NUM"}] matcher.add(keyword, [pattern1, pattern2]) # PDF文本提取函数 def extract_pdf_text(pdf_path): doc = fitz.open(pdf_path) full_text = "" for page in doc: full_text += page.get_text() # 基础清洗:合并多余空格和换行 full_text = " ".join(full_text.split()) return full_text # 批量处理PDF文件 result_list = [] # 替换为你的PDF文件路径列表 pdf_file_list = ["file1.pdf", "file2.pdf", "file3.pdf"] for pdf_path in pdf_file_list: text = extract_pdf_text(pdf_path) doc = nlp(text) matches = matcher(doc) for match_id, start, end in matches: keyword = nlp.vocab.strings[match_id] matched_span = doc[start:end] # 提取匹配到的数值 matched_num = [token.text for token in matched_span if token.pos_ == "NUM"][0] result_list.append({ "pdf_file_name": pdf_path, "matched_keyword": keyword, "extracted_value": matched_num, "context": matched_span.text }) # 导出结果到Excel result_df = pd.DataFrame(result_list) result_df.to_excel("关键词数值提取结果.xlsx", index=False)
效率优化建议
如果后续需要处理上百份甚至更多PDF,仅需给PDF文本提取步骤增加多进程逻辑即可,spaCy的匹配环节耗时极低可以忽略不计,单进程每秒可处理上万字的文本内容。
内容的提问来源于stack exchange,提问作者technophile_3
相关产品推荐
相关产品推荐

