import time from PyPDF2 import PdfReader # 确保已安装 PyPDF2: pip install PyPDF2 from docx import Document import fitz from flask_app.general.llm.qianwen_plus import qianwen_plus from flask_app.general.llm.通义千问long import upload_file, qianwen_long def pre_judge(few_pages_content: str): if few_pages_content.strip() == "": return "未知" # 使用大模型进行判断 user_query = f""" 一, 任务描述: 我会给定一段从文件中摘取出来的文本, 你需要根据该文本的内容来判断文件是否属于招标文件。 二, 判断准则: 以下是常见的招标文件类型: 公开招标文件、邀请招标文件、竞争性谈判文件、竞争性磋商文件、询价文件、问询文件、货物类招标文件、工程类招标文件、施工类招标文件、服务类招标文件、比选文件。 若有未涵盖的类型,但其内容明确表达了项目需求、采购或招标信息,且包含指导投标人参与的关键要素,则可视为招标文件。 排除情况: 1. 请注意区分招标文件和投标文件,若文件仅有投标文件格式要求部分,或是投标、响应性文件,则不视为招标文件。 2. 若文件内容为乱码,无有效信息,请直接返回"否"。 三, 注意事项: 你并不是完全依赖于判断准则来给出判断, 而是根据自己对招标文件的理解来判断, 给定判断准则只是帮助你进行理解。 四, 回答格式: 你的回答只能为"是","否","未知"三种情况之一, 不要在回答中进行任何的解释或输出其他不属于"是","否","未知"的字符。 五, 给定从文件中摘取出来的文本: {few_pages_content} 提问: 该内容是否属于招标文件? 如果属于返回"是"; 如果不属于则返回"否"; 如果你无法判断则返回"未知", 不要进行假设性判断, 不理解就返回"未知"。 """ start_time = time.time() model_res = qianwen_plus(user_query) end_time = time.time() print(f"pre_judge 判断是否属于招标文件:{model_res} 实际耗时:{end_time - start_time:.2f} 秒") if "是" in model_res: return "是" elif "否" in model_res: return "否" else: return "未知" def judge_zbfile_exec(file_path, end_page=5, max_len=3000): """ 判断文件是否属于招标文件,并返回结果。 """ try: start_time = time.time() few_pages_content = "" # 检查文件是否为PDF格式 if file_path.lower().endswith('.pdf'): try: with open(file_path, 'rb') as f: reader = PdfReader(f) num_pages = len(reader.pages) if num_pages > end_page: few_pages_content = "".join([reader.pages[i].extract_text() for i in range(end_page)]) except Exception: try: doc = fitz.open(file_path) num_pages = len(doc) if num_pages > end_page: few_pages_content = "".join([doc.load_page(i).get_text() for i in range(end_page)]) except Exception: print("PDF 文件读取失败") return False # 两种解析方式都失败,直接返回 False if num_pages <= 5: return False # 小于等于 5 页的 PDF 直接判定为非招标文件 few_pages_content = few_pages_content[:max_len] elif file_path.lower().endswith('.docx'): try: doc = Document(file_path) accumulated_text = "" chunk_size = 10 # 每次读取10个段落 paragraphs = doc.paragraphs for i in range(0, len(paragraphs), chunk_size): chunk = paragraphs[i:i + chunk_size] for para in chunk: accumulated_text += para.text if len(accumulated_text) >= max_len: break # 读取超过1000字后即可停止 if len(accumulated_text) < 1000: return False # 若累计内容不足1000字,则直接返回 False except Exception: print("DOCX 文件读取失败,可能为乱码文件") return False # 解析失败直接返回 False few_pages_content = accumulated_text[:max_len] # pre_judge -> 是, 否, 未知 pre_res = pre_judge(few_pages_content) if pre_res != "未知": return '否' not in pre_res pre_endtime=time.time() print(f"judge_zbfile_exec预处理耗时:{pre_endtime - start_time:.2f} 秒") # 使用大模型进行判断 user_query = """该文件是否属于招标文件?如果是的话,请返回'是',如果不是的话,返回'否'。请不要返回其他解释或内容。 以下是常见的招标文件类型: 公开招标文件、邀请招标文件、竞争性谈判文件、竞争性磋商文件、询价文件、问询文件、货物类招标文件、工程类招标文件、施工类招标文件、服务类招标文件、比选文件。 若有未涵盖的类型,但其内容明确表达了项目需求、采购或招标信息,且包含指导投标人参与的关键要素,则可视为招标文件。 排除情况: 1. 请注意区分招标文件和投标文件,若文件仅有投标文件格式要求部分,或是投标、响应性文件,则不视为招标文件。 2. 若文件内容为乱码,无有效信息,请直接返回'否'。 请基于上述内容判断文件是否属于招标文件。 """ file_id = upload_file(file_path) model_res = qianwen_long(file_id, user_query) end_time = time.time() print(f"judge_zbfile_exec实际耗时:{end_time - start_time:.2f} 秒") print(f"qianwen_long 判断是否属于招标文件:{model_res} 实际耗时:{end_time - start_time:.2f} 秒") return '否' not in model_res except Exception as e: print(f"处理文件时出错: {e}") return False if __name__ == '__main__': start_time = time.time() pdf_path = r"C:\Users\Administrator\Desktop\fsdownload\19f53a17-ad4c-43b5-a7ed-981958ec3e0fs\ztbfile.docx" res = judge_zbfile_exec(pdf_path) if res: print("yes") else: print("no") end_time = time.time() print(f"整个程序实际耗时:{end_time - start_time:.2f} 秒")