基于Python Fitz的PDF工具:如何提取含关键词的完整句子
问题描述
开发一款针对标准化法律文档(无图片、无特殊字符)的PDF内容提取工具,需求如下:
- 搜索指定关键词,返回包含该关键词的完整句子
- 根据提取的句子更新检查清单
目前脚本仅能返回关键词所在页码,需优化以实现完整句子提取,推测可通过分隔符提取句号间内容。现有代码如下:
import fitz import re search_word = ("x", "y", "z") results = {} docs = fitz.open("some_pdf.pdf") for page in docs: word = [w[4].lower() for w in page.get_text("word")] for sword in search_words: ###loops through search list### for word in words: ### a search word is part of a word on the page if sword in words: pages = results.get(sword, set()) ### gets a set of page numbers so far page.add(page.number) ### adds a page number resultsp[sword] = pages ### writes back to results ###REPORT OF RESULTS### for word in results: results = list(map(str, results[word])) ### returns set of page numbers page_list = ",".join(results) ### adds a comma to separate page numeber print("word '%s' occurs on pages %s. % (word, page_list)) ###OUTPUT### word 'x' occurs on pages n, n+1, n+2 word 'y' occurs on pages n, n+4, n+6 word 'z' occurs on pages n+25, n+20
解决方案
针对需求,对代码做以下优化:
- 直接获取整页文本而非拆分单词,便于后续按句子分割
- 使用正则表达式匹配包含关键词的完整句子(适配法律文档以句号结尾的标准化格式)
- 重构结果存储结构,同时记录关键词所在页码及对应句子
- 优化输出格式,清晰展示关键词、页码及匹配到的句子
优化后的完整代码:
import fitz import re # 定义要搜索的关键词 search_words = ("x", "y", "z") # 重构结果存储结构:{关键词: {页码: [句子列表]}} results = {word: {} for word in search_words} docs = fitz.open("some_pdf.pdf") for page in docs: page_num = page.number + 1 # 页码从1开始更符合阅读习惯 # 获取整页文本,处理换行符统一为空格 page_text = page.get_text().replace("\n", " ").strip() # 遍历每个关键词 for sword in search_words: # 正则匹配包含关键词的完整句子:匹配前一个句号(或文本开头)到后一个句号之间的内容 # 用re.escape处理关键词,避免特殊字符干扰;启用IGNORECASE忽略大小写 pattern = re.compile(r'(?:^|\. )(.*?{}.*?)(?=\. |$)'.format(re.escape(sword)), re.IGNORECASE) matches = pattern.findall(page_text) if matches: # 如果该页码未在当前关键词的结果中,初始化列表 if page_num not in results[sword]: results[sword][page_num] = [] # 去重后添加匹配到的句子 unique_sentences = list(set(matches)) results[sword][page_num].extend(unique_sentences) # 输出结果 for word in results: print(f"关键词 '{word}' 的匹配结果:") if not results[word]: print(" 无匹配内容\n") continue for page_num, sentences in results[word].items(): print(f" 页码 {page_num}:") for idx, sentence in enumerate(sentences, 1): # 还原句子完整格式:开头大写+结尾补句号 full_sentence = f"{sentence.strip().capitalize()}." print(f" {idx}. {full_sentence}") print()
代码说明
- 文本获取:使用
page.get_text()获取整页文本,替换换行符为空格,避免因换行导致句子拆分 - 正则匹配:
- 用
re.escape()处理关键词,避免特殊字符干扰正则匹配 - 匹配规则:从文本开头或句号+空格开始,到下一个句号+空格或文本结尾结束,确保提取完整句子
- 启用
re.IGNORECASE忽略大小写,适配文档中关键词的不同大小写形式
- 用
- 结果存储:用嵌套字典存储,键为关键词,值为{页码: 句子列表},便于后续更新检查清单
- 结果输出:按关键词、页码、句子的层级展示,同时还原句子的完整格式
内容的提问来源于stack exchange,提问作者Ravi Thehidden
相关产品推荐
相关产品推荐

