123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171 |
- import fitz # PyMuPDF
- import argparse
- import os
- class PDFTextFinder:
- def __init__(self, pdf_path):
- """
- 初始化PDF文本查找器
-
- Args:
- pdf_path: PDF文件路径
- """
- self.pdf_path = pdf_path
- # 检查文件是否存在
- if not os.path.exists(pdf_path):
- raise FileNotFoundError(f"错误: 文件 {pdf_path} 不存在!")
-
- # 打开PDF文件
- self.doc = fitz.open(pdf_path)
-
- def __del__(self):
- """
- 析构函数,确保关闭PDF文件
- """
- if hasattr(self, 'doc') and self.doc:
- self.doc.close()
-
- def find_text(self, search_text):
- """
- 在PDF中查找文本并返回所在页码
-
- Args:
- search_text: 要查找的文本
-
- Returns:
- list: 包含文本出现的页码列表,页码从1开始
- """
- result_pages = []
-
- # 遍历所有页面
- for page_num in range(len(self.doc)):
- page = self.doc.load_page(page_num)
- text_instances = page.search_for(search_text) # 搜索文本
-
- if text_instances: # 如果找到了文本
- # 页码从0开始,所以需要+1
- result_pages.append(page_num + 1)
-
- return result_pages
-
- def find_text_with_context(self, search_text, context_words=20):
- """
- 在PDF中查找文本并返回所在页码及上下文
-
- Args:
- search_text: 要查找的文本
- context_words: 返回的上下文单词数量
-
- Returns:
- list: 包含字典的列表,每个字典包含页码、文本位置和上下文
- """
- results = []
-
- # 遍历所有页面
- for page_num in range(len(self.doc)):
- page = self.doc.load_page(page_num)
- text_instances = page.search_for(search_text) # 搜索文本
-
- if text_instances: # 如果找到了文本
- # 获取页面文本
- page_text = page.get_text()
-
- # 对于每个找到的实例,提取上下文
- for inst in text_instances:
- # 找到文本在页面中的位置
- text_pos = page_text.find(search_text)
- if text_pos >= 0:
- # 计算上下文的起始和结束位置
- start_pos = max(0, text_pos - context_words * 5) # 估算每个单词平均5个字符
- end_pos = min(len(page_text), text_pos + len(search_text) + context_words * 5)
-
- # 提取上下文
- context = page_text[start_pos:end_pos]
-
- # 添加到结果列表
- results.append({
- 'page': page_num + 1, # 页码从0开始,所以需要+1
- 'position': inst, # 文本的位置信息
- 'context': context # 上下文
- })
-
- return results
- def find_text_in_pdf(pdf_path, search_text):
- """
- 在PDF中查找文本并打印所在页码
-
- Args:
- pdf_path: PDF文件路径
- search_text: 要查找的文本
- """
- try:
- finder = PDFTextFinder(pdf_path)
- pages = finder.find_text(search_text)
-
- if pages:
- print(f"在文件 '{pdf_path}' 中找到文本 '{search_text}' 的页码:")
- for page in pages:
- print(f"第 {page} 页")
- print(f"总共在 {len(pages)} 个页面中找到匹配文本。")
- else:
- print(f"在文件 '{pdf_path}' 中没有找到文本 '{search_text}'。")
-
- return pages
- except Exception as e:
- print(f"查找文本时出错: {str(e)}")
- return []
- def find_text_with_context_in_pdf(pdf_path, search_text, context_words=20):
- """
- 在PDF中查找文本并打印所在页码及上下文
-
- Args:
- pdf_path: PDF文件路径
- search_text: 要查找的文本
- context_words: 返回的上下文单词数量
- """
- try:
- finder = PDFTextFinder(pdf_path)
- results = finder.find_text_with_context(search_text, context_words)
-
- if results:
- print(f"在文件 '{pdf_path}' 中找到文本 '{search_text}' 的位置:")
- for result in results:
- print(f"第 {result['page']} 页:")
- print(f"上下文: {result['context']}")
- print("-" * 50)
- print(f"总共找到 {len(results)} 处匹配。")
- else:
- print(f"在文件 '{pdf_path}' 中没有找到文本 '{search_text}'。")
-
- return results
- except Exception as e:
- print(f"查找文本时出错: {str(e)}")
- return []
- def main():
- # 解析命令行参数
- parser = argparse.ArgumentParser(description='在PDF中查找文本并返回页码')
- parser.add_argument('--pdf', required=True, help='PDF文件路径')
- parser.add_argument('--text', required=True, help='要查找的文本')
- parser.add_argument('--context', action='store_true', help='是否显示上下文')
- parser.add_argument('--context_words', type=int, default=20, help='上下文单词数量')
-
- args = parser.parse_args()
-
- # 检查文件是否存在
- if not os.path.exists(args.pdf):
- print(f"错误: 文件 {args.pdf} 不存在!")
- return
-
- print(f"开始在文件 '{args.pdf}' 中查找文本 '{args.text}'...")
-
- # 根据是否需要上下文调用不同的函数
- if args.context:
- find_text_with_context_in_pdf(args.pdf, args.text, args.context_words)
- else:
- find_text_in_pdf(args.pdf, args.text)
- if __name__ == "__main__":
- main()
|