find_text_in_pdf.py 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. import fitz # PyMuPDF
  2. import argparse
  3. import os
  4. class PDFTextFinder:
  5. def __init__(self, pdf_path):
  6. """
  7. 初始化PDF文本查找器
  8. Args:
  9. pdf_path: PDF文件路径
  10. """
  11. self.pdf_path = pdf_path
  12. # 检查文件是否存在
  13. if not os.path.exists(pdf_path):
  14. raise FileNotFoundError(f"错误: 文件 {pdf_path} 不存在!")
  15. # 打开PDF文件
  16. self.doc = fitz.open(pdf_path)
  17. def __del__(self):
  18. """
  19. 析构函数,确保关闭PDF文件
  20. """
  21. if hasattr(self, 'doc') and self.doc:
  22. self.doc.close()
  23. def find_text(self, search_text):
  24. """
  25. 在PDF中查找文本并返回所在页码
  26. Args:
  27. search_text: 要查找的文本
  28. Returns:
  29. list: 包含文本出现的页码列表,页码从1开始
  30. """
  31. result_pages = []
  32. # 遍历所有页面
  33. for page_num in range(len(self.doc)):
  34. page = self.doc.load_page(page_num)
  35. text_instances = page.search_for(search_text) # 搜索文本
  36. if text_instances: # 如果找到了文本
  37. # 页码从0开始,所以需要+1
  38. result_pages.append(page_num + 1)
  39. return result_pages
  40. def find_text_with_context(self, search_text, context_words=20):
  41. """
  42. 在PDF中查找文本并返回所在页码及上下文
  43. Args:
  44. search_text: 要查找的文本
  45. context_words: 返回的上下文单词数量
  46. Returns:
  47. list: 包含字典的列表,每个字典包含页码、文本位置和上下文
  48. """
  49. results = []
  50. # 遍历所有页面
  51. for page_num in range(len(self.doc)):
  52. page = self.doc.load_page(page_num)
  53. text_instances = page.search_for(search_text) # 搜索文本
  54. if text_instances: # 如果找到了文本
  55. # 获取页面文本
  56. page_text = page.get_text()
  57. # 对于每个找到的实例,提取上下文
  58. for inst in text_instances:
  59. # 找到文本在页面中的位置
  60. text_pos = page_text.find(search_text)
  61. if text_pos >= 0:
  62. # 计算上下文的起始和结束位置
  63. start_pos = max(0, text_pos - context_words * 5) # 估算每个单词平均5个字符
  64. end_pos = min(len(page_text), text_pos + len(search_text) + context_words * 5)
  65. # 提取上下文
  66. context = page_text[start_pos:end_pos]
  67. # 添加到结果列表
  68. results.append({
  69. 'page': page_num + 1, # 页码从0开始,所以需要+1
  70. 'position': inst, # 文本的位置信息
  71. 'context': context # 上下文
  72. })
  73. return results
  74. def find_text_in_pdf(pdf_path, search_text):
  75. """
  76. 在PDF中查找文本并打印所在页码
  77. Args:
  78. pdf_path: PDF文件路径
  79. search_text: 要查找的文本
  80. """
  81. try:
  82. finder = PDFTextFinder(pdf_path)
  83. pages = finder.find_text(search_text)
  84. if pages:
  85. print(f"在文件 '{pdf_path}' 中找到文本 '{search_text}' 的页码:")
  86. for page in pages:
  87. print(f"第 {page} 页")
  88. print(f"总共在 {len(pages)} 个页面中找到匹配文本。")
  89. else:
  90. print(f"在文件 '{pdf_path}' 中没有找到文本 '{search_text}'。")
  91. return pages
  92. except Exception as e:
  93. print(f"查找文本时出错: {str(e)}")
  94. return []
  95. def find_text_with_context_in_pdf(pdf_path, search_text, context_words=20):
  96. """
  97. 在PDF中查找文本并打印所在页码及上下文
  98. Args:
  99. pdf_path: PDF文件路径
  100. search_text: 要查找的文本
  101. context_words: 返回的上下文单词数量
  102. """
  103. try:
  104. finder = PDFTextFinder(pdf_path)
  105. results = finder.find_text_with_context(search_text, context_words)
  106. if results:
  107. print(f"在文件 '{pdf_path}' 中找到文本 '{search_text}' 的位置:")
  108. for result in results:
  109. print(f"第 {result['page']} 页:")
  110. print(f"上下文: {result['context']}")
  111. print("-" * 50)
  112. print(f"总共找到 {len(results)} 处匹配。")
  113. else:
  114. print(f"在文件 '{pdf_path}' 中没有找到文本 '{search_text}'。")
  115. return results
  116. except Exception as e:
  117. print(f"查找文本时出错: {str(e)}")
  118. return []
  119. def main():
  120. # 解析命令行参数
  121. parser = argparse.ArgumentParser(description='在PDF中查找文本并返回页码')
  122. parser.add_argument('--pdf', required=True, help='PDF文件路径')
  123. parser.add_argument('--text', required=True, help='要查找的文本')
  124. parser.add_argument('--context', action='store_true', help='是否显示上下文')
  125. parser.add_argument('--context_words', type=int, default=20, help='上下文单词数量')
  126. args = parser.parse_args()
  127. # 检查文件是否存在
  128. if not os.path.exists(args.pdf):
  129. print(f"错误: 文件 {args.pdf} 不存在!")
  130. return
  131. print(f"开始在文件 '{args.pdf}' 中查找文本 '{args.text}'...")
  132. # 根据是否需要上下文调用不同的函数
  133. if args.context:
  134. find_text_with_context_in_pdf(args.pdf, args.text, args.context_words)
  135. else:
  136. find_text_in_pdf(args.pdf, args.text)
  137. if __name__ == "__main__":
  138. main()