standard_pdf_extractor.py 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. import fitz # PyMuPDF
  2. from pdfminer.pdfparser import PDFParser
  3. from pdfminer.pdfdocument import PDFDocument
  4. from pdfminer.pdfpage import PDFPage
  5. from pdfminer.pdfinterp import PDFResourceManager, PDFPageInterpreter
  6. from pdfminer.converter import PDFPageAggregator
  7. from pdfminer.layout import LAParams, LTTextBoxHorizontal, LTLine, LTRect, LTImage
  8. import chardet
  9. def extract_text_from_pdf(pdf_path):
  10. """ 提取文本内容 """
  11. resource_manager = PDFResourceManager()
  12. device = PDFPageAggregator(resource_manager, laparams=LAParams())
  13. interpreter = PDFPageInterpreter(resource_manager, device)
  14. extracted_text = []
  15. with open(pdf_path, 'rb') as fh:
  16. pages = PDFPage.get_pages(fh, caching=True, check_extractable=True)
  17. for page in pages:
  18. interpreter.process_page(page)
  19. layout = device.get_result()
  20. for element in layout:
  21. if isinstance(element, LTTextBoxHorizontal):
  22. content = element.get_text().strip()
  23. try:
  24. extracted_text.append(content)
  25. except Exception as e:
  26. print(f"Error encoding text")
  27. return '\n'.join(extracted_text)
  28. def detect_graphic_objects(pdf_path):
  29. """ 检测图形对象(直线、矩形) """
  30. document = fitz.open(pdf_path)
  31. graphic_objects = []
  32. for page_num in range(len(document)):
  33. page = document.load_page(page_num)
  34. shapes = page.get_drawings()
  35. for shape in shapes:
  36. if 'l' in shape: # 直线
  37. graphic_objects.append(('line', shape['l']))
  38. elif 'rect' in shape: # 矩形
  39. graphic_objects.append(('rect', shape['rect']))
  40. return graphic_objects
  41. def detect_tables(pdf_path):
  42. """ 检测表格 """
  43. resource_manager = PDFResourceManager()
  44. device = PDFPageAggregator(resource_manager, laparams=LAParams())
  45. interpreter = PDFPageInterpreter(resource_manager, device)
  46. tables = []
  47. with open(pdf_path, 'rb') as fh:
  48. pages = PDFPage.get_pages(fh, caching=True, check_extractable=True)
  49. for page in pages:
  50. interpreter.process_page(page)
  51. layout = device.get_result()
  52. # 检测表格的方法:查找相邻的矩形和文本框
  53. boxes = [element for element in layout if isinstance(element, LTRect)]
  54. text_boxes = [element for element in layout if isinstance(element, LTTextBoxHorizontal)]
  55. for box in boxes:
  56. # 查找与矩形相邻的文本框
  57. adjacent_text_boxes = [
  58. tb for tb in text_boxes
  59. if abs(tb.y0 - box.y0) < 10 or abs(tb.y1 - box.y1) < 10 or
  60. abs(tb.x0 - box.x0) < 10 or abs(tb.x1 - box.x1) < 10
  61. ]
  62. if adjacent_text_boxes:
  63. tables.append({
  64. 'bbox': box.bbox,
  65. 'adjacent_text_boxes': adjacent_text_boxes
  66. })
  67. return tables
  68. def detect_images(pdf_path):
  69. """ 检测图像 """
  70. document = fitz.open(pdf_path)
  71. images = []
  72. for page_num in range(len(document)):
  73. page = document.load_page(page_num)
  74. image_list = page.get_images(full=True)
  75. for img_index, img in enumerate(image_list):
  76. xref = img[0]
  77. base_image = document.extract_image(xref)
  78. for k in base_image.keys():
  79. print("**************" + k)
  80. # 确保字典中有 'stream' 键
  81. if 'image' in base_image:
  82. image_bytes = base_image['image']
  83. else:
  84. image_bytes = b'' # 如果没有 'stream' 键,设置为空字节串
  85. image_ext = base_image["ext"]
  86. image_bbox = page.get_image_bbox(img)
  87. images.append({
  88. 'page': page_num + 1,
  89. 'index': img_index,
  90. 'bbox': image_bbox,
  91. 'format': image_ext,
  92. 'data': image_bytes
  93. })
  94. return images
  95. def main(path_of_job:str):
  96. import os
  97. os.makedirs(path_of_job+"/ocr_output", exist_ok=True)
  98. for root,dirs,files in os.walk(path_of_job+"/upload"):
  99. for f in files:
  100. if f.endswith(".pdf"): # 只处理 PDF 文件
  101. pdf_file = os.path.join(root, f)
  102. # 提取文本内容
  103. extracted_text = extract_text_from_pdf(pdf_file)
  104. print("Extracted Text:")
  105. try:
  106. with open(path_of_job+"/ocr_output/"+f+".txt", "w", encoding="utf-8") as f:
  107. f.write(extracted_text)
  108. except Exception as e:
  109. print(f"Error writing file {path_of_job+"/output/"+f+".txt"}")
  110. # # 检测图形对象
  111. # graphic_objects = detect_graphic_objects(pdf_file)
  112. # print("\nDetected Graphic Objects:")
  113. # for obj in graphic_objects:
  114. # obj_type, obj_data = obj
  115. # if obj_type == 'line':
  116. # print(f"Line from ({obj_data[0]}, {obj_data[1]}) to ({obj_data[2]}, {obj_data[3]})")
  117. # elif obj_type == 'rect':
  118. # print(f"Rectangle at ({obj_data[0]}, {obj_data[1]}, {obj_data[2]}, {obj_data[3]})")
  119. # # 检测表格
  120. # tables = detect_tables(pdf_file)
  121. # print("\nDetected Tables:")
  122. # for table in tables:
  123. # print(f"Table at bbox {table['bbox']} with {len(table['adjacent_text_boxes'])} adjacent text boxes")
  124. # # 检测图像
  125. # images = detect_images(pdf_file)
  126. # print("\nDetected Images:")
  127. # for img in images:
  128. # print(f"Image on page {img['page']} at bbox {img['bbox']} with format {img['format']}")
  129. # f = open("image"+str(img['index'])+"."+img['format'], "wb")
  130. # f.write(img['data'])
  131. # f.close()
  132. if __name__ == "__main__":
  133. import sys
  134. # 检查命令行参数
  135. if len(sys.argv) != 2:
  136. print("Usage: python script.py <path_of_job>")
  137. sys.exit(-1)
  138. path_of_job = sys.argv[1]
  139. print(dir(fitz))
  140. main(path_of_job)
  141. # 解释
  142. # 导入必要的模块:
  143. # fitz(PyMuPDF)用于解析 PDF 的图形对象和图像。
  144. # PDFMiner.six 的相关模块用于解析 PDF 的文本内容。
  145. # 定义函数 extract_text_from_pdf:
  146. # 使用 PDFMiner.six 提取 PDF 文件中的文本内容。
  147. # 初始化 PDF 资源管理器、设备和解释器。
  148. # 打开 PDF 文件并获取所有页面。
  149. # 遍历每个页面,处理页面布局。
  150. # 对于每个文本框(LTTextBoxHorizontal),提取文本并存储。
  151. # 定义函数 detect_graphic_objects:
  152. # 使用 PyMuPDF 检测 PDF 文件中的图形对象(如直线、矩形)。
  153. # 打开 PDF 文件并加载每一页。
  154. # 获取每一页的绘图对象。
  155. # 检查绘图对象中是否有直线或矩形,并将其添加到 graphic_objects 列表中。
  156. # 定义函数 detect_tables:
  157. # 使用 PDFMiner.six 检测 PDF 文件中的表格。
  158. # 初始化 PDF 资源管理器、设备和解释器。
  159. # 打开 PDF 文件并获取所有页面。
  160. # 遍历每个页面,处理页面布局。
  161. # 对于每个表格(LTTable),检测并存储。
  162. # 定义函数 detect_images:
  163. # 使用 PyMuPDF 检测 PDF 文件中的图像。
  164. # 打开 PDF 文件并加载每一页。
  165. # 获取每一页的图像列表。
  166. # 提取每个图像的 XREF、格式、边界框和数据。
  167. # 将图像信息存储在 images 列表中。
  168. # 定义主函数 main:
  169. # 调用 extract_text_from_pdf 函数提取文本内容并打印。
  170. # 调用 detect_graphic_objects 函数检测图形对象并打印。
  171. # 调用 detect_tables 函数检测表格并打印。
  172. # 调用 detect_images 函数检测图像并打印。