123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160 |
- from .... import logger,fitz,BytesIO,sys
- from .nlp_Processor import SpacyNLP,NLTKNLP
- class PDFProcessor:
- """
- PDF文件处理器,用于解析PDF文件并处理每一页的内容。
- Attributes:
- file_content (BytesIO): PDF文件的内容。
- document_id (str): 文档的唯一标识符。
- max_tokens (int): 处理文本时的最大令牌数限制。
- bucket_name (str): 用于存储处理结果的存储桶名称。
- KbmService: KbmService对象,用于提供文本处理和存储服务。
- Methods:
- process_pdf(): 解析PDF文件并处理每一页的内容,包括文本和图片。
- """
- def __init__(self, nlp_type=1):
- """
- 初始化PDF处理器,根据指定的NLP类型选择合适的NLP处理器。
- Args:
- nlp_type (int, optional): 指定NLP处理器的类型。1为SpacyNLP,2为NLTKNLP。默认为1。
- """
-
- # self.nlp = SpacyNLP() if nlp_type == 1 else NLTKNLP() if nlp_type == 2 else None
- self.nlp = SpacyNLP()
-
- def get_results(self, file_content, document_id, max_tokens, bucket_name, KbmService):
- """
- 解析PDF文件并处理每一页的内容,包括文本和图片。
- Args:
- file_content (BytesIO): PDF文件的内容。
- document_id (str): 文档的ID。
- max_tokens (int): 最大令牌数。
- bucket_name (str): 存储桶的名称。
- KbmService: KbmService对象。
- Returns:
- tuple: 包含处理后的句子列表和页面图片列表的元组。
- """
- self.file_content = file_content
- self.document_id = document_id
- self.max_tokens = max_tokens
- self.bucket_name = bucket_name
- self.KbmService = KbmService
- # 初始化日志信息,表示开始解析PDF
- sentences = None
- logger.info("开始解析pdf")
- processed_pages, current_pages = self._process_pdf() # 解析PDF文件并处理每一页的内容
- try:
- sentences = self._split_sentences(processed_pages,max_tokens) # 将处理后的页面列表分割成句子列表
- except Exception as e:
- logger.error(f"错误{str(e)}")
-
- logger.info('PDFProcessor处理完成')
- return sentences, current_pages
-
- def _process_pdf(self):
- """
- 解析PDF文件并处理每一页的内容。
- Returns:
- list: 处理后的页面列表。
- """
- processed_pages = [] # 初始化处理后的页面列表
- current_pages =[]
- pdf_reader = None
- try:
- # 检查文件内容是否为BytesIO对象
- if isinstance(self.file_content, BytesIO):
- # 如果是BytesIO对象,则打开PDF文件
- pdf_reader = fitz.open(stream=self.file_content, filetype="pdf")
- else:
- # 如果不是BytesIO对象,则抛出ValueError异常
- raise ValueError(f"文件内容不是BytesIO对象。类型:{type(self.file_content)}")
- except Exception as e:
- # 如果在打开PDF时发生异常,则记录错误日志并返回空列表
- logger.error(f"打开PDF失败:{str(e)}")
- raise ValueError(f"打开PDF失败:{str(e)} {sys._getframe().f_lineno}")
- # 遍历PDF中的每一页
- for page_index in range(len(pdf_reader)):
- current_page = pdf_reader[page_index] # 获取当前页
- page_imag = self._process_page_images(current_page) # 处理页面图片
- page_text = self._extract_page_text(current_page, pdf_reader) # 提取当前页的文本内容
- processed_pages.append(page_text) # 将当前页的文本内容添加到处理后的页面列表中
- current_pages.append(page_imag)
- pdf_reader.close()
- return processed_pages,current_pages
-
- def _extract_page_text(self, page, pdf_reader):
- """
- 提取PDF页面的文本内容。
- Args:
- page (fitz.Page): 需要提取文本的PDF页面对象。
- pdf_reader (fitz.Document): PDF文件的阅读器对象。
- Returns:
- str: 页面的文本内容。
- """
- page_text = page.get_text() # 获取页面的文本内容
- for image_info in page.get_images():
- image_xref = image_info[0] # 获取图片的引用
- extracted_image = pdf_reader.extract_image(image_xref) # 提取图片
- raw_image_data = extracted_image["image"] # 获取图片的raw数据
- if isinstance(raw_image_data, bytes):
- extracted_text = self.KbmService.extract_text_from_image(raw_image_data) # 从图片中提取文本
- if extracted_text and len(extracted_text) > 5:
- page_text += extracted_text
- return page_text
-
- def _process_page_images(self, processed_pages):
- """
- 处理页面图片,渲染页面为图像,保存到MinIO,并记录图像名称。
- Args:
- processed_pages (list): 处理后的页面列表。
- Returns:
- list: 包含页面号和图像名称的元组列表。
- """
- page_images =[]
-
- try:
- # 遍历处理后的页面列表
- page_image = self.KbmService.render_page_to_image(processed_pages)
- # 保存图像到MinIO,并获取图像名称
- image_name = self.KbmService.save_image_to_minio(page_image, self.bucket_name)
- # 将页面号和图像名称作为元组添加到page_images列表中
- page_images.append(image_name)
- except Exception as e:
- logger.error(f'错误')
- # 返回包含所有页面图像信息的列表
- return page_images
-
- def _split_sentences(self, processed_pages,cmax_tokens=250):
- """
- 使用NLP将处理后的内容分割成句子。
- Args:
- processed_pages (list): 处理后的页面列表。
- Returns:
- list: 包含分割后的句子的列表。
- """
- # 初始化一个空列表,用于存储分割后的句子
- sentence_list = []
- # 遍历处理后的页面列表
- for page_text in processed_pages:
- # 使用SNLP模型处理文本,
- sentence_list.append( self.nlp.split_text_into_chunks(page_text,cmax_tokens))
- # 返回包含所有分割后的句子的列表
- return sentence_list
|