This commit is contained in:
zy123 2024-12-16 13:56:28 +08:00
parent a1eb667fb7
commit 119c7715b5
8 changed files with 50 additions and 47 deletions

View File

@ -49,7 +49,7 @@ def convert_pdf_to_markdown(file_path):
image = get_file_content(file_path)
resp = textin.recognize_pdf2md(image, {
'page_start': 0,
'page_count': 50, # 设置解析页数为50页
'page_count': 100, # 设置解析页数为50页
'table_flavor': 'html', # html 按html语法输出表格
'parse_mode': 'auto', # 设置解析模式为scan模式
'page_details': 0, # 不包含页面细节
@ -75,6 +75,6 @@ def convert_pdf_to_markdown(file_path):
if __name__ == "__main__":
# file_path=r"C:\Users\Administrator\Desktop\fsdownload\e702f1e6-095d-443d-bb7d-ef2e42037cb1\ztbfile_procurement.pdf"
file_path=r"C:\Users\Administrator\Desktop\货物标\output1\招标文件实高电子显示屏_procurement.pdf"
file_path=r"C:\Users\Administrator\Desktop\招标文件-采购类\2024-云南-云南省森林消防总队昆明支队室内体能训练馆及训练场建设项目训练设施及训练器材采购项目.pdf"
res=convert_pdf_to_markdown(file_path)
print(res)

View File

@ -3,7 +3,7 @@ import json
import re
from flask_app.general.format_date import format_chinese_date
from flask_app.general.format_amout import format_amount
from flask_app.routes.接口_技术偏离表 import extract_matching_keys, prepare_for_zige_info, \
from flask_app.routes.偏离表main import extract_matching_keys, prepare_for_zige_info, \
process_functions_in_parallel

View File

@ -4,8 +4,9 @@ import re
import time
from concurrent.futures import ThreadPoolExecutor
from flask_app.general.doubao import doubao_model, generate_full_user_query
from docx import Document
from flask_app.general.通用功能函数 import process_string_list
from collections import OrderedDict
from docx import Document
# 只读取前附表中的最后一列(省钱,但容易漏内容)
@ -128,9 +129,6 @@ def preprocess_paragraphs(paragraphs):
#如果当前段落有序号,则向下匹配直接遇到相同的序号样式
#如果当前段落无序号,则向下匹配序号,把若干同类的序号都摘出来。
def extract_text_with_keywords(doc_path, keywords, follow_up_keywords):
from collections import OrderedDict
from docx import Document
import re
if isinstance(keywords, str):
keywords = [keywords]
@ -221,9 +219,9 @@ def extract_text_with_keywords(doc_path, keywords, follow_up_keywords):
found_next_number = False
current_section_pattern = None
while current_index < len(doc.paragraphs) - 1:
while current_index < len(processed_paragraphs) - 1:
current_index += 1
next_text = doc.paragraphs[current_index].text.strip()
next_text = processed_paragraphs[current_index].strip()
if not found_next_number:
# 修改后的正则,支持 '数字 、' 格式
next_section_number = re.match(r'^([A-Za-z0-9]+(?:[.][A-Za-z0-9]+)*)|(\(\d+\))|(\d+\s*、)',
@ -264,7 +262,7 @@ new_text_list = ["这是第一句。", "1. 接下来是第二句!", "(3) 最
def preprocess_text_list(text_list):
new_text_list = []
# 正则表达式匹配中文字符或标点后的空格,该空格后紧跟字母、数字或带括号的数字
split_pattern = re.compile(r'(?<=[\u4e00-\u9fff。?!;])(?=\s+[a-zA-Z\d]|\s+\([1-9]\d*\)|\s+\[1-9]\d*\)')
split_pattern = re.compile(r'(?<=[\u4e00-\u9fff。?!;])(?=\s+[a-zA-Z\d]|\s+\([1-9]\d*\)|\s+\[1-9]\d*\)') #。;!??!;
for text in text_list:
# 使用正则表达式检查并拆分元素
parts = split_pattern.split(text)
@ -286,7 +284,7 @@ def clean_dict_datas(extracted_contents, keywords, excludes): # 让正则表达
if any(exclude in data for exclude in excludes):
continue # 如果包含任何排除字符串,跳过这个数据
# 去掉开头的序号eg:1 | (1) |2 | 1. | 2全角点| 3、 | 1.1 | 2.3.4 | A1 | C1.1 | 一、
pattern = r'^\s*([(]\d+[))]|[A-Za-z]?\d+\s*(\.\s*\d+)*[\s\.、.)\]|[一二三四五六七八九十]+、)'
pattern = r'^\s*(?:[(]\d+[))]|[A-Za-z]?\d+(?:\.\s*\d+)*[\s\.、.)\]?|[一二三四五六七八九十]+、)'
data = re.sub(pattern, '', data).strip()
keyword_match = re.search(keywords, data)
if keyword_match:
@ -316,7 +314,7 @@ def clean_dict_datas(extracted_contents, keywords, excludes): # 让正则表达
# print("*********")
new_text_list = preprocess_text_list(text_list)
# 用于处理结构化文本,清理掉不必要的序号,并将分割后的段落合并,最终形成更简洁和格式化的输出。
pattern = r'^\s*([(]\d+[))]|[A-Za-z]?\d+\s*(\.\s*\d+)*[\s\.、.)\]|[一二三四五六七八九十]+、)'
pattern = r'^\s*(?:[(]\d+[))]|[A-Za-z]?\d+(?:\.\s*\d+)*[\s\.、.)\]?|[一二三四五六七八九十]+、)'
data = re.sub(pattern, '', new_text_list[0]).strip() # 去除序号
# 将修改后的第一个元素和剩余的元素连接起来
@ -367,10 +365,10 @@ def extract_table_with_keywords(data, keywords, follow_up_keywords):
# 2. 分割句子,保证句子完整性(按标点符号和序号分割)
split_sentences = re.split(
r'(?<=[。!?!?\?])|' # 在中文句号、感叹号、问号或分号后面分割
r'(?=\d+[.]\d+)|' # 在类似1.1的数字序号前分割
r'(?=\d+\s(?![号条款节章项例页段部步点年月日时分秒个]))|' # 数字后面跟空格且空格后面不是指定关键字时分割
r'(?=\d+[、.])|' # 在数字后直接跟顿号、半角点号或全角点号时分割
r'(?<=[。!?!?\?])|' # 在中文句号、感叹号、问号或分号后面分割
r'(?=\d+(?:[.]\d+)+)(?!\s*[号条款节章项例页段部步点年月日时分秒个元万])|' # 在类似1.1 1.1.1 的数字序号前分割
r'(?=\d+\s(?!\s*[号条款节章项例页段部步点年月日时分秒个元万]))|' # 数字后面跟空格且空格后面不是指定关键字时分割
r'(?=\d+[、.])(?!\s*[号条款节章项例页段部步点年月日时分秒个元万])|' # 在数字后直接跟顿号、半角点号或全角点号时分割
r'(?=[A-Za-z][.]\s*)|' # 在字母加点如A.、a.)前分割
r'(?=[A-Za-z]+\s*\d+\s*(?:[.]\s*\d+)*)|' # 在可选字母加数字或多级编号前分割
r'(?=[一二三四五六七八九十]+、)', # 在中文数字加顿号(如一、二、)前分割
@ -412,6 +410,7 @@ def extract_table_with_keywords(data, keywords, follow_up_keywords):
full_text = ' '.join(split_sentences[start_index:]).strip()
# 清洗文本,去除前缀编号等
pattern = r'^\s*([(]\d+[)]|[A-Za-z][.]\s*|[A-Za-z]?\d+\s*([.]\s*\d+)*(\s|[.]|、|)?|[一二三四五六七八九十]+、)'
full_text = re.sub(pattern, '', full_text).replace(' ', '').strip()
sentences2.append(full_text) # 存储有后续关键词的情况
@ -468,7 +467,7 @@ def handle_query(file_path, user_query, output_file, result_key, keywords):
follow_up_keywords = [r'\s*形\s*之\s*一', r'\s*况\s*之\s*一', r'\s*列', r'\s*下','\s*他\s*情\s*形\s*','\s*他\s*情\s*形\s*:']
extracted_contents = extract_text_with_keywords(file_path, [keywords], follow_up_keywords) # 字典结果
all_texts1, all_texts2 = clean_dict_datas(extracted_contents, keywords, excludes) # 列表
# table_data_list=read_docx_last_column(truncate_file) #从投标人须知前附表中提取信息生成列表data每个元素为'一行信息'
# table_data_list=read_docx_last_column(file_path) #从投标人须知前附表中提取信息生成列表data每个元素为'一行信息'
table_data_list = read_tables_from_docx(file_path)
all_tables1, all_tables2 = extract_table_with_keywords(table_data_list, keywords, follow_up_keywords)
qianwen_txt = all_texts1 + all_tables1
@ -527,22 +526,22 @@ def combine_find_invalid(file_path, output_dir):
os.path.join(output_dir, "temp1.txt"),
"否决和无效投标情形"
),
(
r'\s*标',
"""以下是从招标文件中摘取的内容,文本内之间的信息以'...............'分割,请你根据该内容回答:废标项的情况有哪些?文本中可能存在无关的信息,请你准确筛选符合的信息并将它的序号返回。请以[x,x,x]格式返回给我结果x为符合的信息的序号若情况不存在返回[]。
文本内容{full_text}
""",
os.path.join(output_dir, "temp2.txt"),
"废标项"
),
(
r'\s*得|禁\s*止\s*投\s*标',
"""以下是从招标文件中摘取的内容,文本内之间的信息以'...............'分割,每条信息规定了各方不得存在的情形,请回答:在这些信息中,投标人或中标人或供应商或联合体投标各方或磋商小组不得存在的情形或禁止投标的情形有哪些?不要返回主语是招标人或采购人或评标委员会的信息,请你筛选所需的信息并将它的序号返回。请以[x,x,x]格式返回给我结果,示例返回为[1,4,6],若情形不存在,返回[]。以下为需要考虑的注意事项:请返回包含实际内容的信息,若信息内容诸如'投标人不得存在的其他关联情形'这样笼统的表格,而未说明具体的情形,则无需添加这条信息。
文本内容{full_text}
""",
os.path.join(output_dir, "temp3.txt"),
"不得存在的情形"
)
# (
# r'废\s*标',
# """以下是从招标文件中摘取的内容,文本内之间的信息以'...............'分割,请你根据该内容回答:废标项的情况有哪些?文本中可能存在无关的信息,请你准确筛选符合的信息并将它的序号返回。请以[x,x,x]格式返回给我结果x为符合的信息的序号若情况不存在返回[]。
# 文本内容:{full_text}
# """,
# os.path.join(output_dir, "temp2.txt"),
# "废标项"
# ),
# (
# r'不\s*得|禁\s*止\s*投\s*标',
# """以下是从招标文件中摘取的内容,文本内之间的信息以'...............'分割,每条信息规定了各方不得存在的情形,请回答:在这些信息中,投标人或中标人或供应商或联合体投标各方或磋商小组不得存在的情形或禁止投标的情形有哪些?不要返回主语是招标人或采购人或评标委员会的信息,请你筛选所需的信息并将它的序号返回。请以[x,x,x]格式返回给我结果,示例返回为[1,4,6],若情形不存在,返回[]。以下为需要考虑的注意事项:请返回包含实际内容的信息,若信息内容诸如'投标人不得存在的其他关联情形'这样笼统的表格,而未说明具体的情形,则无需添加这条信息。
# 文本内容:{full_text}
# """,
# os.path.join(output_dir, "temp3.txt"),
# "不得存在的情形"
# )
]
results = []
@ -582,8 +581,8 @@ if __name__ == '__main__':
# truncate_file="C:\\Users\\Administrator\\Desktop\\货物标\\output4\\招标文件实高电子显示屏_tobidders_notice_part1.docx"
# clause_path = "D:\\flask_project\\flask_app\\static\\output\\output1\\77a48c63-f39f-419b-af2a-7b3dbf41b70b\\clause1.json"
# doc_path="C:\\Users\\Administrator\\Desktop\\货物标\\zbfilesdocx\\磋商文件(1).docx"
doc_path = r'C:\Users\Administrator\Desktop\fsdownload\457ee03d-c61c-4672-b959-2bbb35a1de29\ztbfile.docx'
output_dir = r"C:\Users\Administrator\Desktop\fsdownload\457ee03d-c61c-4672-b959-2bbb35a1de29\tmp"
doc_path = r'C:\Users\Administrator\Desktop\fsdownload\140aae9a-0dac-4bba-be57-ea706af069d6\ztbfile_invalid.docx'
output_dir = r"C:\Users\Administrator\Desktop\fsdownload\140aae9a-0dac-4bba-be57-ea706af069d6\tmp"
results = combine_find_invalid(doc_path, output_dir)
end_time = time.time()
print("Results:", json.dumps(results, ensure_ascii=False, indent=4))

View File

@ -4,7 +4,7 @@ from flask import Blueprint, jsonify, Response, g
import json
import os
from flask_app.general.format_change import download_file
from flask_app.routes.接口_技术偏离表 import get_tech_and_business_deviation
from flask_app.routes.偏离表main import get_tech_and_business_deviation
from flask_app.routes.utils import generate_deviation_response, validate_and_setup_logger
from flask_app.ConnectionLimiter import require_connection_limit
get_deviation_bp = Blueprint('get_deviation', __name__)

View File

@ -6,7 +6,7 @@ from flask import Blueprint, jsonify, g
from flask_app.ConnectionLimiter import require_connection_limit
from flask_app.general.format_change import download_file
from flask_app.routes.接口_小解析 import little_parse_main
from flask_app.routes.小解析main import little_parse_main
from flask_app.routes.utils import validate_and_setup_logger
little_zbparse_bp = Blueprint('little_zbparse', __name__)

View File

@ -1,13 +1,8 @@
import json
import re
import string
from collections import OrderedDict
from collections import defaultdict
#传输技术参数需求的时候后处理
def extract_matching_keys(data, good_list, special_keys=None, parent_key=''):
import re
from collections import defaultdict
def get_suffix(n):
"""
根据数字n返回对应的字母后缀
@ -52,6 +47,15 @@ def extract_matching_keys(data, good_list, special_keys=None, parent_key=''):
if isinstance(value, list):
# 处理值为列表的键
if any(pattern.match(clean_key) for pattern in patterns):
# 检查是否以特殊符号开头
if clean_key.startswith(('', '','','','','','','','','')):
symbol = clean_key[0]
stripped_key = clean_key[1:]
new_key = generate_key(stripped_key, parent_key, key_counter, suffix_map, special_keys)
# 将符号添加到每个字符串的开头
new_value = [symbol + item for item in value]
filtered_data[new_key] = new_value
else:
new_key = generate_key(clean_key, parent_key, key_counter, suffix_map, special_keys)
filtered_data[new_key] = value
elif isinstance(value, dict):
@ -245,8 +249,8 @@ def remove_common_prefixes(string_list, min_occurrence=3):
if __name__ == "__main__":
# 示例数据
sample_data = {
"交通信号机": [
"应采用区域控制信号机,并应与广水市交通信号控制系统兼容,信号机能接入已有系统平台,实现联网优化功能。",
"交通信号机": [
"应采用区域控制信号机,并应与广水市交通信号控制系统兼容,信号机能接入已有系统平台,实现联网优化功能。",
"1、控制功能1区域协调控制可对单个孤立交叉口、干道多个交叉口和关联性较强的交叉口群进行综合性地信号控制。",
"1、控制功能2线性协调控制可对干道多个相邻交叉口进行协调控制。",
"1、控制功能3多时段控制可根据交叉口的交通状况将每天划分为多个不同的时段每个时段配置不同的控制方案能设置至少 10个时段、10种以上不同控制方案能根据不同周日类型对方案进行调整。信号机能够根据内置时钟选择各个时段的控制方案实现交叉口的合理控制。",
@ -254,7 +258,7 @@ if __name__ == "__main__":
"2、采集功能2信号机支持交通信息采集与统计,并支持交通流量共享。",
"3、运维功能1信号机能够自动检测地磁故障若故障能够自动上传故障信息至监控中心。"
],
"高清视频抓拍像机": [
"高清视频抓拍像机": [
"1摄像机有效像素≥900W像素",
"1摄像机最低照度彩色≤0.001lx",
"1摄像机传感器类型≥1英寸全局曝光 COMS/GMOS/GS COMS",