11.1适配货物标

This commit is contained in:
zy123 2024-11-01 17:55:26 +08:00
parent 7cd92c253d
commit 206bc6276f
8 changed files with 285 additions and 546 deletions

View File

@ -20,7 +20,8 @@ def format_chinese_date(date_str):
# print("------------")
# print(f"原始输入: {date_str}")
# 预处理:删除第一个数字之前的所有字符
date_str = re.sub(r'^[^\d]*', '', date_str)
# 1. 删除所有空格
date_str = ''.join(date_str.split())
@ -109,7 +110,7 @@ def format_chinese_date(date_str):
if __name__ == "__main__":
input_dates = [
# 完整的日期和时间
"2021年 6月 18日 15点 00分",
"开标日期是2021年 6月 18日 15点 00分",
"2019年7月18日0930",
"20 19 年7 月18日 09 30整北京时间",
"2020年02月05日12时30分45秒",

View File

@ -157,7 +157,7 @@ def extract_pages_tobidders_notice(pdf_path, output_folder, begin_pattern, begin
)
else:
end_pattern = re.compile(
rf'第[一二三四五六七八九十百千]+?(?:{chapter_type})\s*[\u4e00-\u9fff]+\s*$'
rf'第[一二三四五六七八九十百千]+(?:章|部分)\s*[\u4e00-\u9fff]+\s*$'
)
# print(f"使用默认的 end_pattern: {end_pattern.pattern}") # 打印默认的 end_pattern
# 定义基础的 mid_pattern

View File

@ -4,7 +4,10 @@
3.该招标文件的最高限价或招标控制价或预算金额请按json格式给我提供信息键名为'招标控制价',若存在未知信息,在对应的键值中填'未知'。
4.投标文件或响应文件递交截止时间是请按json格式给我提供信息键名是'投标文件递交截止日期',若存在未知信息,在对应的键值中填'未知'。
4.投标文件或响应文件递交截止时间是请按json格式给我提供信息键名是'投标文件递交截止日期',键值为原文对应的内容,若存在未知信息,在对应的键值中填'未知'。示例输出格式如下:
{
"投标文件递交截止日期":"以本项目在湖北省政府采购网招标公告为准(北京时间)。"
}
5.采购人招标人和采购代理机构或招标代理机构和项目的联系方式是请按json格式给我提供信息外层键名分别是'招标人联系方式''招标代理机构联系方式'"项目联系方式",嵌套键名至少包含"名称"和"联系电话",若还有其他字段则添加在后面,若存在未知信息,在对应的键值中填'未知'。示例输出如下:
{
@ -25,7 +28,11 @@
6.该招标文件的信息公示媒介在哪请按json格式给我提供信息键名是'信息公示媒介',若存在未知信息,在对应的键值中填'未知'。
7.该项目的开标时间或开启时间和开标地点是请按json格式给我提供信息键名为'开标时间'和'开标地点',若存在未知信息,在对应的键值中填'未知'。
7.该项目的开标时间或开启时间和开标地点或开标方式请按json格式给我提供信息键名为'开标时间'和'开标地点',键值为原文对应的内容,若存在未知信息,在对应的键值中填'未知'。示例输出格式如下:
{
"开标时间":"以本项目在湖北省政府采购网招标公告为准(北京时间)。",
"开标地点":"供应商通过供应商客户端进入江夏区政府采购电子交易系统开标大厅中进行远程开启"
}
8.请你根据招标文件信息投标人需要递交的投标保证金或磋商保证金是多少请按json格式给我提供信息键名为'投标保证金额',键值为原文中的具体金额的完整表述,如果不需要递交保证金或者金额未知,键值为"其他"。

View File

@ -1,480 +1,144 @@
def post_process_baseinfo(base_info):
# -*- encoding:utf-8 -*-
import json
import re
def is_numeric_key(key):
# 这个正则表达式匹配由数字、点、括号中的数字或单个字母(小写或大写)组成的字符串,
# 字母后跟数字,或数字后跟字母,单个字母后跟点,但不能是字母-数字-字母的组合
pattern = r'^[\d.]+$|^\(\d+\)$|^\d+$|^[a-zA-Z]$|^[a-zA-Z]\d+$|^\d+[a-zA-Z]$|^[a-zA-Z]\.$'
return re.match(pattern, key) is not None
def contains_number_or_index(key, value):
# 判断值是否是数字或数字字符串
is_number = isinstance(value, (int, float)) or (isinstance(value, str) and value.isdigit())
# 判断键是否包含 "序号"
contains_index = '序号' in key
# 判断值中是否包含数字
contains_digit = isinstance(value, str) and re.search(r'\d+', value)
# 判断值中是否包含中文字符
contains_chinese = isinstance(value, str) and re.search(r'[\u4e00-\u9fff]', value)
# 如果值中包含数字但也有中文字符,则保留(返回 False
if contains_digit and contains_chinese:
return False
# 如果值是数字或包含数字,且不包含中文字符,或者键包含 "序号",返回 True
return is_number or contains_index or contains_digit
def preprocess_dict(data):
if isinstance(data, dict):
if len(data) > 1:
# 检查是否所有值都是 "" 或 "/"
if all(v == "" or v == "/" or (isinstance(v, list) and not v) for v in data.values()):
return list(data.keys())
else:
processed = {}
for k, v in data.items():
if not contains_number_or_index(k, v):
processed_v = preprocess_dict(v)
if processed_v != "": # 只添加非空值
processed[k] = processed_v
return processed
else:
return {k: preprocess_dict(v) for k, v in data.items()}
elif isinstance(data, list):
return [preprocess_dict(item) for item in data]
else:
return data
def process_dict(data):
"""
'base_info' 任务完成后执行的函数
确保在缺少某些键时返回 good_list=[]
递归处理字典将符合条件的键值对进行转换
参数
- base_info (dict): 原始的 base_info 数据
如果键是数字或特定格式的字符串则将其值放入 'items' 列表中并排序
对于非数字键如果对应的值是列表且列表中只有一个元素则将其展平为单个元素
返回
- tuple: (处理后的 base_info, good_list)
Args:
data (dict): 输入的字典数据
Returns:
dict list 原始数据类型: 处理后的数据结构
"""
try:
pure_base_info = base_info.get("基础信息", {})
# 尝试提取 '货物列表',若中间某个键不存在,返回 good_list=[]
procurement_reqs = pure_base_info.get('采购要求', {})
technical_requirements = procurement_reqs.get('技术要求', {})
good_list = technical_requirements.pop('货物列表', []) # 如果 '货物列表' 不存在,返回 []
if not isinstance(data, dict):
return data
# 删除 '货物列表' 后更新原始的 base_info
if '技术要求' in procurement_reqs and not technical_requirements:
# 若技术要求为空,删除该键
procurement_reqs.pop('技术要求')
result = {}
numeric_keys = []
non_numeric_keys = {}
if '采购要求' in pure_base_info and not procurement_reqs:
# 若采购要求为空,删除该键
pure_base_info.pop('采购要求')
# 分类键为数字键和非数字键
for key, value in data.items():
if is_numeric_key(key):
numeric_keys.append((key, value))
else:
non_numeric_keys[key] = value
# 更新基础信息
base_info['基础信息'] = pure_base_info
# 处理数字键,将其值递归处理后放入 'items' 列表中
if numeric_keys:
def sort_key(item):
key = item[0]
if re.match(r'^\d+$', key): # 纯整数
return (int(key),)
elif re.match(r'^\d+\.\d+$', key): # 单层小数点
return (float(key),)
else: # 多层序号,按字符串处理
return tuple(map(int, key.split('.')))
# 按键排序,确保顺序一致
numeric_keys_sorted = sorted(numeric_keys, key=sort_key)
result['items'] = [process_dict(item[1]) for item in numeric_keys_sorted]
return base_info, good_list
except Exception as e:
return base_info, [] # 返回空列表
# 处理非数字键
for key, value in non_numeric_keys.items():
if isinstance(value, list):
processed_list = []
for item in value:
if isinstance(item, dict):
# 处理字典中只有一个键值对的情况
if len(item) == 1:
processed_item = process_dict(list(item.values())[0])
else:
processed_item = process_dict(item)
else:
processed_item = process_dict(item)
# 如果处理后的项是只包含一个元素的列表,则展平它
if isinstance(processed_item, list) and len(processed_item) == 1:
processed_item = processed_item[0]
processed_list.append(processed_item)
# 新增逻辑:如果 processed_list 只有一个元素,则将其展平为单个元素
if len(processed_list) == 1:
result[key] = processed_list[0]
else:
result[key] = processed_list
else:
# 如果值不是列表,直接递归处理
result[key] = process_dict(value)
# 如果结果只有一个键 'items',则直接返回 'items' 列表
if len(result) == 1 and 'items' in result:
return result['items']
# 检查如果所有键对应的值都是空列表,则将键名转换成列表项
if all(isinstance(v, list) and not v for v in result.values()):
return list(result.keys())
return result
data={
"基础信息": {
"招标人/代理信息": {
"招标人": "广水市公路管理局",
"招标人联系方式": {
"名称": "广水市公路管理局",
"联系电话": "17362698785",
"地址": "随州市广水市四贤路 7号应山办事处南门"
},
"招标代理机构": "湖北众恒永业工程项目管理有限公司广水分公司",
"招标代理机构联系方式": {
"名称": "湖北众恒永业工程项目管理有限公司广水分公司",
"联系电话": "13997896775",
"地址": "广水市名都花园 22栋"
},
"项目联系方式": {
"名称": "闵杨、喻亚",
"联系电话": "13997896775、15337331616"
}
},
"项目信息": {
"项目名称": "107国道交通信号灯及安全防护设施采购项目",
"项目编号": "HBZHYY-2021-001",
"项目概况": "107国道交通信号灯及安全防护设施采购项目",
"项目基本情况": {
"1": "政府采购计划编号2020-09-000560",
"2": "项目编号HBZHYY-2021-001",
"3": "项目名称107国道交通信号灯及安全防护设施采购项目",
"4": "采购方式:公开招标",
"5": "预算金额RMB10071358.07元",
"6": "最高限价RMB10070194.68元(一包:RMB6230708.59元、二包:RMB2175838.09元、三包:RMB1663648元",
"7": {
"7.1": "项目概况及内容一包107国道交通信号灯及安全防护设施的监控抓拍系统、电子警察、信号灯、专用配套设备等。二包107国道广水段标示标牌及标线等。三包107国道霞家河超限检测站抓拍、超重系统等。以上具体要求见招标文件第三章项目技术、服务及商务要求。",
"7.2": "项目地点107国道路段。",
"7.3": "投标人只能对此项目三个包中的一个包进行报名,若同时对两个包或两个包以上进行报名,则所有报名无效。"
},
"8": "合同履行期限:合同签订后 6个月内。",
"9": "本项目不接受联合体投标。",
"10": "是否可采购进口产品:否。"
},
"招标控制价": "RMB10070194.68元",
"投标竞争下浮率": "未知",
"分包": "不允许",
"是否接受联合体投标": ""
},
"采购要求": {
"技术要求": {
"交通信号灯": {
"单灯技术要求": "1、道路交通信号灯单灯必须符合国家标准GB14887-2011《道路交通信号灯》全部技术规定并通过公安部交通安全产品质量监督检测中心的检测。",
"光源要求": "2、道路交通信号灯光源必须采用户外型超亮度发光二极管LED使用寿命不少于50000小时。",
"材质要求": "3、信号灯灯具材质为铝质金属材料。机动车信号灯灯芯透镜尺寸采用¢400mm规格人行信号灯灯芯透镜尺寸采用¢300mm相同规格的灯芯可以互换。信号灯外观应与目前广水市使用的信号灯外观相一致。",
"供电电路要求": "4、信号灯需采用恒流供电电路单体信号灯功率¢400mm规格不超过20VA¢300mm规格不超过 15VA。",
"倒计时器要求": "1、道路交通信号倒计时器安装在信号灯的上方或右方2位数码显示倒九秒提示。当机动车信号灯采用悬臂式杆件时机动车信号灯倒计时器规格为 800×600当采用立柱式杆件时倒计时器规格为 400×400。人行信号灯倒计时显示器透光面为Φ300mm或 300mm ×300mm。倒计时显示器的光学性能、工作条件、机械强度、电气性能均符合国家安全行业标准GA/T508-2004《道路交通信号倒计时显示器》的全部技术规定。",
"倒计时器运行要求": "2、倒计时器运行中遇到电磁、静电、电网等干扰时不能有死机现象。",
"倒计时器测试要求": "3、倒计时器必须经过过电压、过电流测试具有防雷击功能。",
"倒计时器触发方式": "4、倒计时器应为学习型并支持脉冲触发、黄灯触发及通讯式触发。",
"信号灯杆技术要求": "1、信号灯杆所属的立柱、法兰盘、地脚螺栓、螺母、垫片、加强筋等金属构件及悬臂、支撑臂、拉杆、抱箍座、夹板等附件的防腐性能应符合GB/T18226《公路交通工程钢构件防腐技术条件》的规定。",
"信号灯杆材质要求": "2、信号灯杆应采用圆形或多棱形经热镀锌处理的钢管制造悬臂式灯杆悬臂杆与支撑杆使用圆形或多棱形的变截面型材制作悬臂与灯杆连接端宜焊接固定法兰盘悬臂下应留有进出线孔。",
"信号灯杆表面处理": "3、信号灯杆制作后须经过防锈处理底层喷涂富锌防锈底漆外层喷涂银灰色瓷漆。",
"信号灯杆底部要求": "4、信号灯灯杆距路面约 300-350mm处留有拉线孔和拉线孔门。孔门盖应设有防盗措施孔内设置接地端子座并与接地线可靠接驳。",
"信号灯杆顶部要求": "5、立柱式灯杆顶部安装灯具处应留有出线孔并配备橡胶护套、电缆线回水弯挂钩灯杆顶部应安装塑料或经防腐处理的内套式金属防水管帽。",
"悬臂式灯杆拉杆要求": "6、悬臂式灯杆拉杆宜使用圆钢制作一端配有可调距离的螺旋扣直径和长度根据悬臂长度确定。",
"信号灯杆法兰盘要求": "7、信号灯杆杆体底部应焊接固定法兰盘法兰盘与杆体之间应均匀焊接加强筋。",
"人行信号灯设计要求": "8、一体式人行信号灯采用整灯嵌入式设计、结构紧凑、方便拆装、便于维护。杆体前后金属面板喷塑处理两侧铝型材包边。"
},
"交通监控视频子系统": {
"高清视频抓拍像机": {
"有效像素": "≥900W像素",
"最低照度": "彩色≤0.001lx",
"传感器类型": "≥1英寸全局曝光COMS/GMOS/GS COMS",
"电子快门": "至少满足 1/25s至 1/100,000s可调",
"视频压缩标准": "至少支持H264、H265等",
"视频分辨率": "≥4096×2160向下可设置",
"视频流帧率": "≥25fps,至少双视频流",
"图片压缩方式": "JPEG",
"图像分辨率": "≥4096(H)×2160(V)",
"强光抑制": "具备",
"API接口开放": "具备支持标准ONVIF协议与第三方厂家设备进行互联支持GB/T28181应提供 SDK",
"通讯接口": "≥1个 RJ4510M/100M/1000M自适应以太网电口≥1个 RS-485接口",
"前端存储卡": "嵌入式支持断网时本地存储裸容量≥128GB",
"具备其他功能": "应具备I/O触发、RS-485触发、视频触发支持电源同步支持频闪式卜光装置和脉冲式补光装置同步补光",
"具备其他功能2": "具备AI深度学习算法和GPU芯片",
"光圈、聚焦": "手动光圈;焦距应可根据车道宽度及抓拍距离进行调整设置,要求中心成像圆内解像力不小于 900万像素边缘解像力不低于中心 60%,镜头的成像尺寸应与摄像机成像靶面尺寸相等或略大。镜头应配置电动偏振镜,具备根据环境自动切换功能",
"防护罩类型": "室外型防护罩,含底座;具备隔热防潮、防水、防尘、防腐、防震等功能;具有加热器、支架、遮阳罩等,具有良好的密封性和恒温等功能。",
"防护等级": "≥IP66"
},
"补光灯": {
"配置方式": "每个车道配置≥1台补光装置必须与高清摄像设备高度匹配",
"LED管芯": "采用超高亮大功率白光LED管芯灯珠数量不少于 20颗",
"功耗": "30W/车道≤单台平均功耗≤50W/车道,可调",
"峰值光照度(基准轴)": "≤300lx",
"峰值光照度(补光区)": "应大于等于基准轴上有效光照度的 50%",
"平均光照度": "≤50lx",
"闪光频率": "≥50Hz补光装置应能与集成式高清摄像设备同步",
"有效补光距离": "≥25m",
"最大点亮时间": "≤4ms(可调节)",
"控制方式": "电平,同步触发方式",
"安全性": "在保证瞬时亮度的前提下,必须进行防炫目处理,不会造成光污染",
"使用寿命": "≥50000小时",
"防护等级": "不低于IP65",
"其它": "应配置光栅装置或遮光阻断装置"
},
"光纤收发器": {
"1路千兆以太网": "1路千兆以太网。",
"单模单纤": "单模单纤光接口为FC接口满足实际传输距离要求。",
"10/100/1000M自适应以太网接口": "10/100/1000M自适应以太网接口。",
"工作环境适应性强": "工作环境适应性强,满足全天候使用的要求。",
"耐压": "耐压≥300V。"
},
"交换机": {
"交换容量": "≥6Gbps包转发率≥7MppsMAC地址列表≥8K应具备线性转发能力",
"以太网接口": "应至少具有 8个 10/100/1000M自适应以太网接口和至少 2个 1000M光口",
"以太网光端口传输距离": "应不小于 40km以太网光模块为单芯双向光模块光口接口类型为LC型接口光模块连接单模光纤",
"支持协议": "至少支持 IEEE802.1p、IEEE802.1q、IEEE802.3、IEEE802.3u、IEEE802.3z、IEEE802.3x等协议;",
"VLAN功能": "应具有 IEEE802.1Q VLAN应实现信号控制独立传输至少支持 4个 VLAN划分",
"路由协议": "应至少支持三层动态路由协议;",
"QOS功能": "应具有 IEEE802.1p_QOS功能;",
"组播功能": "应具有 IGMP静态组播、端口聚合、端口镜像等功能",
"防护等级": "IP40以上等级防护",
"设计要求": "应采用无风扇设计;",
"网管功能": "应具有网管功能。"
},
"终端服务器": {
"结构形式": "采用嵌入式架构;",
"操作系统": "嵌入式操作系统;",
"接入路数": "提供≥12路高清摄像机视频存储、过车记录存储、图片存储、数据上传、视频流转发等",
"主机存储": "内置 SATA接口配置存储容量≥16T硬盘 ",
"网络接口": "提供≥8个 RJ45 1000M网络接口",
"其他接口": "提供 RS232、RS485、外置 USB接口、VGA接口等",
"访问操作": "支持 Web操作访问",
"接口协议": "至少支持 ONVIFGB/T28181等",
"API接口开放支持": "支持标准ONVIF协议与第三方厂家设备进行互通支持 GB/T 28181。",
"支持套牌车检测": "可将抓拍图片与本地历史数据进行车辆特征比对分析,检测出套牌车辆,同时给出告警提示"
}
},
"交通诱导子系统": {
"交通诱导屏": {
"主要特性": "1)温度范围-40~70℃ 2)光带宽度>130mm 3)通迅接口RS485、网络通讯、3G网络 4)视角水平110°120°垂直55° 5)发光亮度6500-7000 cd/m2 6)平整度≤0.5mm 7)使用寿命≥10万小时 8)平均故障时间≥1万小时 9)电源采用 n+1高可靠容错的开关电源系统 10)显示尺寸:长 3.84米×高 2.56米=9.83平方米 11)机箱要求:冷轧钢板,机箱为内外两层内箱体为全封闭、全天候、防风雨型符合IP65防护等级 12)抗风等级40m/s",
"技术参数": "1物理点间距10mm2物理密度10000点/m23发光点颜色1R1G 4基色纯红+纯绿 5模组尺寸:320mm*160mm 6刷新频率≥800HZ 7工作电压AC220V±1050Hz三相五线制8平均功耗350W/m2 9最大功耗≤700W/ m2"
}
},
"电子警察子系统": {
"高清视频抓拍像机": {
"摄像机.有效像素": "≥900W像素",
"摄像机.最低照度": "彩色≤0.001lx",
"摄像机.传感器类型": "≥1英寸全局曝光COMS/GMOS/GS COMS",
"摄像机.电子快门": "至少满足 1/25s至 1/100,000s可调",
"视频图像.视频压缩标准": "至少支持H264、H265等",
"视频图像.视频分辨率": "≥4096×2160向下可设置",
"视频图像.视频流帧率": "≥25fps,至少双视频流",
"视频图像.图片压缩方式": "JPEG",
"视频图像.图像分辨率": "≥4096(H)×2160(V)",
"视频图像.强光抑制": "具备",
"协议.API接口开放": "具备支持标准ONVIF协议与第三方厂家设备进行互联支持GB/T28181应提供 SDK",
"接口.通讯接口": "≥1个 RJ4510M/100M/1000M自适应以太网电口≥1 个 RS-485接口",
"接口.前端存储卡": "嵌入式支持断网时本地存储裸容量≥128GB",
"功能.具备其他功能": "应具备I/O触发、RS-485触发、视频触发支持电源同步支持频闪式卜光装置和脉冲式补光装置同步补光",
"功能.具备其他功能.具备AI深度学习算法和GPU芯片": "具备AI深度学习算法和GPU芯片",
"高清工业级镜头.光圈、聚焦": "手动光圈;焦距应可根据车道宽度及抓拍距离进行调整设置,要求中心成像圆内解像力不小于 900万像素边缘解像力不低于中心 60%,镜头的成像尺寸应与摄像机成像靶面尺寸相等或略大。镜头应配置电动偏振镜,具备根据环境自动切换功能",
"防护罩.防护罩类型": "室外型防护罩,含底座;具备隔热防潮、防水、防尘、防腐、防震等功能;具有加热器、支架、遮阳罩等,具有良好的密封性和恒温等功能。",
"防护罩.防护等级": "≥IP66"
},
"补光灯": {
"配置方式": "每个车道配置≥1台补光装置必须与高清摄像设备高度匹配",
"LED管芯": "采用超高亮大功率白光LED管芯灯珠数量不少于 20颗",
"功耗": "30W/车道≤单台平均功耗≤50W/车道,可调",
"峰值光照度(基准轴)": "≤300lx",
"峰值光照度(补光区)": "应大于等于基准轴上有效光照度的 50%",
"平均光照度": "≤50lx",
"闪光频率": "≥50Hz补光装置应能与集成式高清摄像设备同步",
"有效补光距离": "≥25m",
"最大点亮时间": "≤4ms(可调节)",
"控制方式": "电平,同步触发方式",
"安全性": "在保证瞬时亮度的前提下,必须进行防炫目处理,不会造成光污染",
"使用寿命": "≥50000小时",
"防护等级": "不低于IP65",
"其它": "应配置光栅装置或遮光阻断装置"
},
"光纤收发器": {
"1路千兆以太网": "1路千兆以太网。",
"单模单纤": "单模单纤光接口为FC接口满足实际传输距离要求。",
"10/100/1000M自适应以太网接口": "10/100/1000M自适应以太网接口。",
"工作环境适应性强": "工作环境适应性强,满足全天候使用的要求。",
"耐压": "耐压≥300V。"
},
"交换机": {
"交换容量": "≥6Gbps包转发率≥7MppsMAC地址列表≥8K应具备线性转发能力",
"以太网接口": "应至少具有 8个 10/100/1000M自适应以太网接口和至少 2个 1000M光口",
"以太网光端口传输距离": "应不小于 40km以太网光模块为单芯双向光模块光口接口类型为LC型接口光模块连接单模光纤",
"支持协议": "至少支持 IEEE802.1p、IEEE802.1q、IEEE802.3、IEEE802.3u、IEEE802.3z、IEEE802.3x等协议;",
"VLAN功能": "应具有 IEEE802.1Q VLAN应实现信号控制独立传输至少支持 4个 VLAN划分",
"动态路由协议": "应至少支持三层动态路由协议;",
"QOS功能": "应具有 IEEE802.1p_QOS功能;",
"组播功能": "应具有 IGMP静态组播、端口聚合、端口镜像等功能",
"防护等级": "IP40以上等级防护",
"设计要求": "应采用无风扇设计;",
"网管功能": "应具有网管功能。"
},
"终端服务器": {
"结构形式": "采用嵌入式架构;",
"操作系统": "嵌入式操作系统;",
"接入路数": "提供≥12路高清摄像机视频存储、过车记录存储、图片存储、数据上传、视频流转发等",
"主机存储": "内置 SATA接口配置存储容量≥16T硬盘 ",
"网络接口": "提供≥8个 RJ45 1000M网络接口",
"其他接口": "提供 RS232、RS485、外置 USB接口、VGA接口等",
"访问操作": "支持 Web操作访问",
"接口协议": "至少支持 ONVIFGB/T28181等",
"API接口开放支持": "支持标准ONVIF协议与第三方厂家设备进行互通支持 GB/T 28181。",
"支持套牌车检测": "可将抓拍图片与本地历史数据进行车辆特征比对分析,检测出套牌车辆,同时给出告警提示"
}
},
"交通卡口子系统": {
"高清视频抓拍像机": {
"摄像机.有效像素": "≥900W像素",
"摄像机.最低照度": "彩色≤0.001lx",
"摄像机.传感器类型": "≥1英寸全局曝光COMS/GMOS/GS COMS",
"摄像机.电子快门": "至少满足 1/25s至 1/100,000s可调",
"视频图像.视频压缩标准": "至少支持H264、H265等",
"视频图像.视频分辨率": "≥4096×2160向下可设置",
"视频图像.视频流帧率": "≥25fps,至少双视频流",
"视频图像.图片压缩方式": "JPEG",
"视频图像.图像分辨率": "≥4096(H)×2160(V)",
"视频图像.强光抑制": "具备",
"协议.API接口开放": "具备支持标准ONVIF协议与第三方厂家设备进行互联支持GB/T28181应提供 SDK",
"接口.通讯接口": "≥1个 RJ4510M/100M/1000M自适应以太网电口≥1 个 RS-485接口",
"接口.前端存储卡": "嵌入式支持断网时本地存储裸容量≥128GB",
"功能.具备其他功能": "应具备I/O触发、RS-485触发、视频触发支持电源同步支持频闪式卜光装置和脉冲式补光装置同步补光",
"功能.具备其他功能.1": "具备AI深度学习算法和GPU芯片",
"高清工业级镜头.光圈、聚焦": "手动光圈;焦距应可根据车道宽度及抓拍距离进行调整设置,要求中心成像圆内解像力不小于 900万像素边缘解像力不低于中心 60%,镜头的成像尺寸应与摄像机成像靶面尺寸相等或略大。镜头应配置电动偏振镜,具备根据环境自动切换功能",
"防护罩.防护罩类型": "室外型防护罩,含底座;具备隔热防潮、防水、防尘、防腐、防震等功能;具有加热器、支架、遮阳罩等,具有良好的密封性和恒温等功能。",
"防护罩.防护等级": "≥IP66"
},
"补光灯": {
"配置方式": "每个车道配置≥1台补光装置必须与高清摄像设备高度匹配",
"LED管芯": "采用超高亮大功率白光LED管芯灯珠数量不少于 20颗",
"功耗": "30W/车道≤单台平均功耗≤50W/车道,可调",
"峰值光照度(基准轴)": "≤300lx",
"峰值光照度(补光区)": "应大于等于基准轴上有效光照度的 50%",
"平均光照度": "≤50lx",
"闪光频率": "≥50Hz补光装置应能与集成式高清摄像设备同步",
"有效补光距离": "≥25m",
"最大点亮时间": "≤4ms(可调节)",
"控制方式": "电平,同步触发方式",
"安全性": "在保证瞬时亮度的前提下,必须进行防炫目处理,不会造成光污染",
"使用寿命": "≥50000小时",
"防护等级": "不低于IP65",
"其它": "应配置光栅装置或遮光阻断装置"
},
"光纤收发器": {
"1路千兆以太网": "1路千兆以太网。",
"单模单纤": "单模单纤光接口为FC接口满足实际传输距离要求。",
"10/100/1000M自适应以太网接口": "10/100/1000M自适应以太网接口。",
"工作环境适应性强": "工作环境适应性强,满足全天候使用的要求。",
"耐压": "耐压≥300V。"
},
"交换机": {
"交换容量": "≥6Gbps包转发率≥7MppsMAC地址列表≥8K应具备线性转发能力",
"以太网接口": "应至少具有 8个 10/100/1000M自适应以太网接口和至少 2个 1000M光口",
"以太网光端口传输距离": "应不小于 40km以太网光模块为单芯双向光模块光口接口类型为LC型接口光模块连接单模光纤",
"支持协议": "至少支持 IEEE802.1p、IEEE802.1q、IEEE802.3、IEEE802.3u、IEEE802.3z、IEEE802.3x等协议;",
"VLAN功能": "应具有 IEEE802.1Q VLAN应实现信号控制独立传输至少支持 4个 VLAN划分",
"路由协议": "应至少支持三层动态路由协议;",
"QOS功能": "应具有 IEEE802.1p_QOS功能;",
"组播功能": "应具有 IGMP静态组播、端口聚合、端口镜像等功能",
"防护等级": "IP40以上等级防护",
"设计要求": "应采用无风扇设计;",
"网管功能": "应具有网管功能。"
},
"终端服务器": {
"结构形式": "采用嵌入式架构;",
"操作系统": "嵌入式操作系统;",
"接入路数": "提供≥12路高清摄像机视频存储、过车记录存储、图片存储、数据上传、视频流转发等",
"主机存储": "内置 SATA接口配置存储容量≥16T硬盘 ",
"网络接口": "提供≥8个 RJ45 1000M网络接口",
"其他接口": "提供 RS232、RS485、外置 USB接口、VGA接口等",
"访问操作": "支持 Web操作访问",
"接口协议": "至少支持 ONVIFGB/T28181等",
"API接口开放支持": "支持标准ONVIF协议与第三方厂家设备进行互通支持 GB/T 28181。",
"支持套牌车检测": "可将抓拍图片与本地历史数据进行车辆特征比对分析,检测出套牌车辆,同时给出告警提示"
}
},
"区间测速子系统": {
"高清视频抓拍像机": {
"1.摄像机.有效像素": "≥900W像素",
"1.摄像机.最低照度": "彩色≤0.001lx",
"1.摄像机.传感器类型": "≥1英寸全局曝光COMS/GMOS/GS COMS",
"1.摄像机.电子快门": "至少满足 1/25s至 1/100,000s可调",
"2.视频图像.视频压缩标准": "至少支持H264、H265等",
"2.视频图像.视频分辨率": "≥4096×2160向下可设置",
"2.视频图像.视频流帧率": "≥25fps,至少双视频流",
"3.视频图像.图片压缩方式": "JPEG",
"3.视频图像.图像分辨率": "≥4096(H)×2160(V)",
"3.视频图像.强光抑制": "具备",
"4.协议.API接口开放": "具备支持标准ONVIF协议与第三方厂家设备进行互联支持GB/T28181应提供 SDK",
"5.接口.通讯接口": "≥1个 RJ4510M/100M/1000M自适应以太网电口≥1 个 RS-485接口",
"5.接口.前端存储卡": "嵌入式支持断网时本地存储裸容量≥128GB",
"5.功能.具备其他功能": "具备AI深度学习算法和GPU芯片",
"6.高清工业级镜头.光圈、聚焦": "手动光圈;焦距应可根据车道宽度及抓拍距离进行调整设置,要求中心成像圆内解像力不小于 900万像素边缘解像力不低于中心 60%,镜头的成像尺寸应与摄像机成像靶面尺寸相等或略大。镜头应配置电动偏振镜,具备根据环境自动切换功能",
"7.防护罩.防护罩类型": "室外型防护罩,含底座;具备隔热防潮、防水、防尘、防腐、防震等功能;具有加热器、支架、遮阳罩等,具有良好的密封性和恒温等功能。",
"7.防护罩.防护等级": "≥IP66"
},
"补光灯": {
"配置方式": "每个车道配置≥1台补光装置必须与高清摄像设备高度匹配",
"LED管芯": "采用超高亮大功率白光LED管芯灯珠数量不少于 20颗",
"功耗": "30W/车道≤单台平均功耗≤50W/车道,可调",
"峰值光照度(基准轴)": "≤300lx",
"峰值光照度(补光区)": "应大于等于基准轴上有效光照度的 50%",
"平均光照度": "≤50lx",
"闪光频率": "≥50Hz补光装置应能与集成式高清摄像设备同步",
"有效补光距离": "≥25m",
"最大点亮时间": "≤4ms(可调节)",
"控制方式": "电平,同步触发方式",
"安全性": "在保证瞬时亮度的前提下,必须进行防炫目处理,不会造成光污染",
"使用寿命": "≥50000小时",
"防护等级": "不低于IP65",
"其它": "应配置光栅装置或遮光阻断装置"
},
"光纤收发器": {
"1路千兆以太网": "1路千兆以太网。",
"单模单纤": "单模单纤光接口为FC接口满足实际传输距离要求。",
"10/100/1000M自适应以太网接口": "10/100/1000M自适应以太网接口。",
"工作环境适应性强": "工作环境适应性强,满足全天候使用的要求。",
"耐压": "耐压≥300V。"
},
"交换机": {
"交换容量": "≥6Gbps",
"包转发率": "≥7Mpps",
"MAC地址列表": "≥8K",
"线性转发能力": "应具备线性转发能力",
"以太网接口": "应至少具有 8个 10/100/1000M自适应以太网接口和至少 2个 1000M光口",
"以太网光端口传输距离": "应不小于 40km以太网光模块为单芯双向光模块光口接口类型为LC型接口光模块连接单模光纤",
"支持协议": "至少支持 IEEE802.1p、IEEE802.1q、IEEE802.3、IEEE802.3u、IEEE802.3z、IEEE802.3x等协议",
"VLAN": "应具有 IEEE802.1Q VLAN应实现信号控制独立传输至少支持 4个 VLAN划分",
"三层动态路由协议": "应至少支持三层动态路由协议",
"QOS功能": "应具有 IEEE802.1p_QOS功能",
"IGMP静态组播": "应具有 IGMP静态组播、端口聚合、端口镜像等功能",
"防护等级": "IP40以上等级防护",
"无风扇设计": "应采用无风扇设计",
"网管功能": "应具有网管功能"
},
"终端服务器": {
"结构形式": "采用嵌入式架构;",
"操作系统": "嵌入式操作系统;",
"接入路数": "提供≥8路高清摄像机视频存储、过车记录存储、图片存储、数据上传、视频流转发等",
"主机存储": "内置 SATA接口配置存储容量≥16T硬盘 ",
"网络接口": "提供≥8个 RJ45 1000M网络接口",
"其他接口": "提供 RS232、RS485、外置 USB接口、VGA接口等",
"访问操作": "支持 Web操作访问",
"接口协议": "至少支持 ONVIFGB/T28181等",
"API接口开放支持": "支持标准ONVIF协议与第三方厂家设备进行互通支持 GB/T 28181。"
}
},
"后台接入服务器": {
"1、机架式服务器": "1、机架式服务器",
"2、处理器": "2、处理器至少配置 2颗单颗 10核 CPU,单核 CPU主频≥2.0GHz",
"3、内存": "3、内存配置 128GB DDR4内存",
"4、硬盘": "4、硬盘配置 6块 1.2T SAS硬盘,转速≥10Krpm",
"5、RAID": "5、RAID配置 RAID控制器支持 RAID0、1、10、1E、5、50、60等",
"6、网络": "6、网络配置双千兆网卡",
"7、电源": "7、电源双电源"
},
"存储服务器": {
"1": "4U 48盘位磁盘阵列",
"2": "单设备配置 64位多核处理器",
"3": "16GB缓存",
"4": "冗余电源;",
"5": "支持 SATA硬盘",
"6": "2个千兆网口",
"7": "1个系统 SSD盘",
"8": "支持视音频、图片、直接写入支持视频高速预览、回放、下载支持云内容灾备份支持一体化运维支持GB/T28181-2011、Onvif、RTSP、H265、SVAC等标准视频协议。"
},
"硬盘": {
"容量": "4T",
"尺寸": "3.5寸",
"接口": "SATA"
},
"室外挂箱": {
"安装方式": "采用悬挂式安装方式,悬挂于杆件立柱,高度应确保机箱下边缘距离地面净高 2.5 米以上。设备机箱安装后不得侵入机动车道建筑界限以内,不得影响车辆正常通行。设备机箱应安装牢固;",
"表面处理": "设备机箱表面应经过考漆处理,应具备防锈蚀、防盐雾、防霉菌能力;",
"内部空间": "机箱内部空间应足够大,能确保设备、装置的合理摆放,设有存放用户手册、说明书、接线图、维修记录等资料的存储盒,并有适当空间预留。机箱空间应有利于机箱内各设备单元的散热、安装、使用和维修,同时应提供设备辅助散热措施,提高系统环境适应能力;",
"防护等级": "设备机箱的结构应能防雨并能降低灰尘及有害物质的侵入机箱门盖应有溢水槽机箱门内侧应配备密封条机箱顶部应具有防积水措施。机箱防护等级应达到IP55以上",
"机械强度": "机箱结构应具有足够的机械强度,应能承受正常条件下可预料到的运输、安装、搬运、维护等过程中的操作;",
"门的设计": "机箱门的最大开启角度应大于 120°。机箱门锁应采用保险柜天地锁式的结构设计防止被非法打开门锁至少可对上、下及左右侧中的一侧进行缩栓式保护应具备较强的设备防砸、防盗能力。机箱应具有防盗报警功能机箱在非正常状态下开启时能够报警提示。机箱门接缝处有耐久且有弹性的密封垫密封垫连续设置无间断接口。机柜门锁上后无松动、变形现象",
"电源保护": "机箱内设应置有具备稳压、过载、漏电、短路保护功能的电源开关和防雷保护功能的电源浪涌保护器。在熔断器和电源开关等处应有警告标志。机箱内合适位置配备接地铜排,接地铜排的截面应不小于 100 mm2接地端子应进行防腐处理。并应设置接地标志接地铜排应保证良好接地接地线截面积应不小于 16mm2",
"电源插座": "机箱内应配备不少于 2路单相 2孔扁圆电源插座、2路单相 3孔扁圆电源插座",
"电源开关": "应具有稳压、短路、过载、漏电保护;电源保护响应时间应为纳秒级;开关的额定电压、额定电流值应满足设备正常运行的要求;机械寿命应不少于 20000次具有良好的散热性能。",
"额外要求": "室外大机箱需满足上述使用外,还应可安装前端管理主机。"
},
"交通管道": {
"过街管道": "主要垂直于道路中线埋设,可开挖路段采用 DN90镀锌钢管不宜开挖路段根据现场情况采用拖拉管DN90 PE管。路口必须在各方向埋设双管。",
"非过街管道": "采用 PE双壁波纹管。",
"干线(纵向)路段": "两接线井之间最大距 50m。",
"管道埋设深度": "机动车道和非机动车道下管道埋设深度管顶至路面应≥0.7m人行道及绿化带下管道埋设深度管顶至路面应≥0.5m。如不能达到上述埋设深度要求应采取混凝土包封或采用钢管等保护措施。",
"管道敷设的坡度": "应为 0.3%-0.4%,不得小于 0.25%",
"其他敷设要求": "应参照《市政公用工程细部构造做法(湖北省)》中《交通管道预埋断面图》做法。",
"交通管道开挖后": "应按原有道路或绿化进行恢复,管线尽量敷设于人行道上,不影响后续的绿化园林施工。"
}
},
"商务要求": "",
"服务要求": "",
"其他要求": ""
},
"关键时间/内容": {
"投标文件递交截止日期": "2021年月日点分北京时间",
"投标文件递交地点": "广水市公共资源交易中心五楼号开标室",
"开标时间": "未知",
"开标地点": "广水市公共资源交易中心五楼号开标室",
"澄清招标文件的截止时间": "未知",
"投标有效期": "提交投标文件截止之日起 60日历日",
"信息公示媒介": [
{
"名称": "中国湖北政府采购网",
"网址": "http://www.ccgp-hubei.gov.cn/"
},
{
"名称": "中国广水网",
"网址": "http://www.zggsw.gov.cn/"
}
]
},
"保证金相关": {
"是否提交履约保证金": "未知",
"质量保证金": "未知"
},
"其他信息": {
"投标费用承担": "投标人应承担所有与准备和参加投标有关的费用。不论投标的结果如何,分散采购机构和采购人均无义务和责任承担这些费用。",
"招标代理服务费": {
"收费标准": "服务费按国家规定收费标准按国家发展改革委关于印发《招标代理服务收费管理暂行办法》的通知(计价格[2002]1980 号)执行。",
"支付方": "中标方",
"支付时间": "政府采购代理缴纳中标服务费"
},
"是否退还投标文件": "",
"投标预备会": "不召开",
"偏离": {
"商务要求响应、偏离说明表": "第七章投标文件格式(参考)附件十二",
"商务要求“★”号条款响应、偏离说明表": "第七章投标文件格式(参考)附件十三",
"技术、服务要求响应、偏离说明表": "第七章投标文件格式(参考)附件十五",
"技术、服务要求“★”号条款响应、偏离说明表": "第七章投标文件格式(参考)附件十六",
"偏离项的具体要求": "未知"
},
"踏勘现场": "不组织",
"货物列表": {}
}
"资格性审查": {
"1": "供应商应具备《政府采购法》第二十二条规定的条件,提供相关材料。",
"2": "法人或者其他组织的营业执照等证明文件,自然人的身份证明;",
"3": "财务状况报告,依法缴纳税收和社会保障资金的声明函;",
"4": "具备履行合同所必需的设备和专业技术能力的证明材料;",
"5": "未被列入信用记录名单声明函;",
"6": "参加政府采购活动前 3年内在经营活动中没有重大违法记录的书面声明",
"7": "具备法律、行政法规规定的其他条件的证明材料;",
"8": "招标文件第一章“投标人资格要求”中有特殊要求的,投标人应提供其符合特殊要求的证明材料或者情况说明;",
"9.1.1": "未被列入信用记录名单声明函;",
"10.1.1": "参加政府采购活动前 3年内在经营活动中没有重大违法记录的书面声明",
"11": "具备法律、行政法规规定的其他条件的证明材料;",
"12": "招标文件第一章“投标人资格要求”中有特殊要求的,投标人应提供其符合特殊要求的证明材料或者情况说明;"
}
}
res1,res2=post_process_baseinfo(data)
print(res1)
res1=process_dict(preprocess_dict(data))
print(json.dumps(res1,ensure_ascii=False,indent=4))

View File

@ -13,8 +13,8 @@ from flask_app.货物标.提取采购需求main import fetch_procurement_reqs
def aggregate_basic_info_goods(baseinfo_list):
for i in baseinfo_list:
print(json.dumps(i,ensure_ascii=False,indent=4))
# for i in baseinfo_list:
# print(json.dumps(i,ensure_ascii=False,indent=4))
"""
将基础信息列表中的数据进行合并和分类

View File

@ -230,24 +230,58 @@ def get_patterns_for_notice_twice():
# return start_page, mid_page, end_page
def extract_pages_tobidders_notice(pdf_document, begin_pattern, begin_page, common_header, exclusion_pattern):
def run_extraction():
"""
从PDF文档中提取起始页中间页和结束页
如果第一次提取失败则使用新的 begin_pattern end_pattern 重新提取
参数:
pdf_document (PDFDocument): 要处理的PDF文档对象
begin_pattern (str re.Pattern): 用于识别起始的正则表达式模式
begin_page (int): 开始搜索的页码
common_header (str): 每页需要清理的公共头部文本
exclusion_pattern (str re.Pattern): 用于排除某些页的模式
返回:
tuple: (start_page, mid_page, end_page) 如果成功否则 (None, None, None)
"""
def run_extraction(local_begin_pattern, local_end_pattern=None):
"""
使用提供的 begin end 模式运行提取过程
如果未提供 local_end_pattern则根据匹配的章节类型动态生成 end_pattern
参数:
local_begin_pattern (str re.Pattern): 用于识别起始的正则表达式模式
local_end_pattern (str re.Pattern, 可选): 用于识别结束的正则表达式模式
返回:
tuple: (start_page, mid_page, end_page)
"""
start_page = None
mid_page = None
end_page = None
chapter_type = None # 用于存储“章”或“部分”
combined_mid_pattern = None # 中间页的组合模式
for i, page in enumerate(pdf_document.pages):
text = page.extract_text() or ""
cleaned_text = clean_page_content(text, common_header)
# 如果已经找到中间页,且当前页匹配排除模式,则跳过
if exclusion_pattern and re.search(exclusion_pattern, cleaned_text) and mid_page is not None:
continue
# 识别起始页
if start_page is None:
match = re.search(begin_pattern, cleaned_text)
match = re.search(local_begin_pattern, cleaned_text)
if match and i > begin_page:
start_page = i
matched_text = match.group(0) # 获取整个匹配的文本
# 如果未提供固定的 end_pattern则根据匹配的章节类型动态生成
if not local_end_pattern:
if '' in matched_text:
chapter_type = ''
elif '部分' in matched_text:
@ -257,11 +291,10 @@ def extract_pages_tobidders_notice(pdf_document, begin_pattern, begin_page, comm
if chapter_type:
# 根据 chapter_type 动态生成 end_pattern
end_pattern = re.compile(
end_pattern_dynamic = re.compile(
rf'^第[一二三四五六七八九十百千]+?(?:{chapter_type})\s*[\u4e00-\u9fff]+',
re.MULTILINE
)
# print(f"动态生成的 end_pattern: {end_pattern.pattern}") # 打印生成的 end_pattern
# 根据 chapter_type 动态生成 additional_mid_pattern
if chapter_type == '':
@ -272,7 +305,8 @@ def extract_pages_tobidders_notice(pdf_document, begin_pattern, begin_page, comm
additional_mid_pattern = ''
# 定义基础的 mid_pattern
base_mid_pattern = r'^\s*(?:[(]\s*[一二12]?\s*[)]\s*[、..]*|[一二12][、..]+|[、..]+)\s*(说\s*明|总\s*则)'
base_mid_pattern = r'^\s*(?:[(]\s*[一二12]?\s*[)]\s*[、..]*|' \
r'[一二12][、..]+|[、..]+)\s*(说\s*明|总\s*则)'
# 合并基础模式和额外模式
if additional_mid_pattern:
@ -285,44 +319,67 @@ def extract_pages_tobidders_notice(pdf_document, begin_pattern, begin_page, comm
rf'{base_mid_pattern}',
re.MULTILINE
)
# print(f"生成的 combined_mid_pattern: {combined_mid_pattern.pattern}") # 打印 combined_mid_pattern
else:
# 如果未匹配到“章”或“部分”,使用默认的 end_pattern 和 mid_pattern
end_pattern = re.compile(
end_pattern_dynamic = re.compile(
r'^第[一二三四五六七八九十百千]+(?:章|部分)\s*[\u4e00-\u9fff]+',
re.MULTILINE
)
print(f"使用默认的 end_pattern: {end_pattern.pattern}") # 打印默认的 end_pattern
# 定义基础的 mid_pattern
base_mid_pattern = r'^\s*(?:[(]\s*[一二12]?\s*[)]\s*[、..]*|[一二12][、..]+|[、..]+)\s*(说\s*明|总\s*则)'
base_mid_pattern = r'^\s*(?:[(]\s*[一二12]?\s*[)]\s*[、..]*|' \
r'[一二12][、..]+|[、..]+)\s*(说\s*明|总\s*则)'
combined_mid_pattern = re.compile(
rf'{base_mid_pattern}',
re.MULTILINE
)
else:
# 如果提供了固定的 end_pattern则使用默认的 mid_pattern
base_mid_pattern = r'^\s*(?:[(]\s*[一二12]?\s*[)]\s*[、..]*|' \
r'[一二12][、..]+|[、..]+)\s*(说\s*明|总\s*则)'
combined_mid_pattern = re.compile(
rf'{base_mid_pattern}',
re.MULTILINE
)
print(
f"使用默认的 combined_mid_pattern: {combined_mid_pattern.pattern}") # 打印默认的 combined_mid_pattern
continue
# 识别中间页
if start_page is not None and mid_page is None and combined_mid_pattern:
if re.search(combined_mid_pattern, cleaned_text):
mid_page = i
if start_page is not None and mid_page is not None and chapter_type:
if re.search(end_pattern, cleaned_text):
# 识别结束页
if start_page is not None and mid_page is not None:
# 使用提供的 end_pattern 或动态生成的 end_pattern
current_end_pattern = local_end_pattern if local_end_pattern else end_pattern_dynamic
if re.search(current_end_pattern, cleaned_text):
if i > mid_page:
end_page = i
break
return start_page, mid_page, end_page
# 运行提取
start_page, mid_page, end_page = run_extraction()
# 第一次提取尝试,使用初始的 begin_pattern
start_page, mid_page, end_page = run_extraction(begin_pattern)
# 如果第一次提取失败,则使用新的 begin_pattern 和 end_pattern 重新提取
if not (start_page and mid_page and end_page):
# 定义新的 begin_pattern 和 end_pattern
new_begin_pattern = re.compile(
r'.*(?:投标人|磋商|供应商|谈判供应商|磋商供应商)须知\s*$|'
r'(?:一\s*、\s*)?(?:投标人?|磋商|供应商)须知前附表',
re.MULTILINE
)
new_end_pattern = re.compile(
r'第[一二三四五六七八九十百千]+(?:章|部分)\s*[\u4e00-\u9fff、]+\s*$',
re.MULTILINE
)
# 第二次提取尝试,使用新的模式
start_page, mid_page, end_page = run_extraction(new_begin_pattern, new_end_pattern)
return start_page, mid_page, end_page
def extract_pages_twice_tobidders_notice(pdf_path, output_folder, output_suffix, common_header):
begin_pattern = re.compile(
r'^第[一二三四五六七八九十百千]+(?:章|部分)\s*(?:(?:投标人?|磋商|供应商|谈判供应商|磋商供应商)须知)+'
@ -674,7 +731,7 @@ def truncate_pdf_specific_goods(pdf_path, output_folder, selections,unique_id="1
# TODO:交通智能系统和招标(1)(1)文件有问题 包头 绍兴 资格审查文件可能不需要默认与"evaluation"同一章 无效投标可能也要考虑 “more”的情况类似工程标 唐山投标只有正文,没有附表
if __name__ == "__main__":
input_path = "C:\\Users\\Administrator\\Desktop\\new招标文件\\货物标\\HBDL-2024-0498-001-招标文件.pdf"
input_path = "C:\\Users\\Administrator\\Desktop\\new招标文件\\货物标\\HBDL-2024-0519-001-招标文件.pdf"
# input_path = "C:\\Users\\Administrator\\Desktop\\fsdownload\\b151fcd0-4cd8-49b4-8de3-964057a9e653\\ztbfile.pdf"
# input_path="C:\\Users\\Administrator\\Desktop\\货物标\\zbfiles"
# input_path = "C:\\Users\\Administrator\\Desktop\\货物标\\output1\\2-招标文件_procurement.pdf"
@ -685,6 +742,6 @@ if __name__ == "__main__":
# selections = [1,4]
# files=truncate_pdf_specific_goods(input_path,output_folder,selections)
print(files)
# selection = 2# 例如1 - 公告, 2 - 评标办法, 3 - 资格审查后缀有qualification1或qualification2与评标办法一致 4.投标人须知前附表part1 投标人须知正文part2 5-采购需求
# selection = 4# 例如1 - 公告, 2 - 评标办法, 3 - 资格审查后缀有qualification1或qualification2与评标办法一致 4.投标人须知前附表part1 投标人须知正文part2 5-采购需求
# generated_files = truncate_pdf_main(input_path, output_folder, selection)
# print(generated_files)

View File

@ -516,11 +516,10 @@ if __name__ == '__main__':
start_time = time.time()
# truncate_json_path = "C:\\Users\\Administrator\\Desktop\\货物标\\output4\\tmp2\\竞争性谈判文件(3)_tobidders_notice_part1\\truncate_output.json"
# truncate_file="C:\\Users\\Administrator\\Desktop\\货物标\\output4\\招标文件实高电子显示屏_tobidders_notice_part1.docx"
clause_path = "D:\\flask_project\\flask_app\\static\\output\\015d997e-c32c-49d1-a611-a2e817ace6a1\\clause1.json"
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 = 'C:\\Users\\Administrator\\Desktop\\fsdownload\\a091d107-805d-4e28-b8b2-0c7327737238\\ztbfile.docx'
output_dir = "C:\\Users\\Administrator\\Desktop\\fsdownload\\a091d107-805d-4e28-b8b2-0c7327737238\\tmp"
doc_path = 'D:\\flask_project\\flask_app\\static\\output\\output1\\77a48c63-f39f-419b-af2a-7b3dbf41b70b\\ztbfile.docx'
output_dir = "D:\\flask_project\\flask_app\\static\\output\\output1\\77a48c63-f39f-419b-af2a-7b3dbf41b70b"
results = combine_find_invalid(doc_path, output_dir)
end_time = time.time()
print("Elapsed time:", str(end_time - start_time))

View File

@ -6,7 +6,7 @@ from flask_app.general.通义千问long import upload_file
from flask_app.general.多线程提问 import multi_threading
from flask_app.general.json_utils import clean_json_string
from flask_app.货物标.投标人须知正文条款提取成json文件货物标版 import convert_clause_to_json
import copy
# 这个字典可能有嵌套,你需要遍历里面的键名,对键名作判断,而不是键值,具体是这样的:如果处于同一层级的键的数量>1并且键名全由数字或点号组成。那么就将这些序号键名全部删除重新组织成一个字典格式的数据你可以考虑用字符串列表来保持部分平级的数据
# 对于同级的键,如果数量>1且键名都统一那么将键名去掉用列表保持它们的键值
@ -87,8 +87,16 @@ def process_dict(data):
# 处理数字键,将其值递归处理后放入 'items' 列表中
if numeric_keys:
def sort_key(item):
key = item[0]
if re.match(r'^\d+$', key): # 纯整数
return (int(key),)
elif re.match(r'^\d+\.\d+$', key): # 单层小数点
return (float(key),)
else: # 多层序号,按字符串处理
return tuple(map(int, key.split('.')))
# 按键排序,确保顺序一致
numeric_keys_sorted = sorted(numeric_keys, key=lambda x: x[0])
numeric_keys_sorted = sorted(numeric_keys, key=sort_key)
result['items'] = [process_dict(item[1]) for item in numeric_keys_sorted]
# 处理非数字键
@ -136,7 +144,7 @@ def find_chapter_clause_references(data, parent_key=""):
exclude_list = ["格式要求"]
result = []
# 正则匹配"第x章"或"第x款"
chapter_clause_pattern = re.compile(r'第[一二三四五六七八九十\d]+[章款]')
chapter_clause_pattern = re.compile(r'第[一1]+[章款]|公告|邀请')
# 如果数据不是字典,则直接返回空列表
if not isinstance(data, dict):
return result
@ -162,7 +170,8 @@ def find_chapter_clause_references(data, parent_key=""):
result.extend(find_chapter_clause_references(item, new_parent_key))
elif isinstance(value, str):
# 如果值是字符串,检查是否匹配"第x章"或"第x款"
if chapter_clause_pattern.search(value):
if chapter_clause_pattern.search(value): #符合|应满足|详见
if "符合"in value or "满足" in value or "详见" in value:
result.append({full_key: value})
return result
@ -202,7 +211,7 @@ def preprocess_value(value):
if target_part:
# 删除开头的"符合"或"应满足"
target_part = re.sub(r'^(符合|应满足)\s*', '', target_part.strip())
target_part = re.sub(r'^(符合|应满足|详见)\s*', '', target_part.strip())
return target_part
# 如果没有找到特定章节或条款,返回原始值
@ -325,6 +334,7 @@ def process_match_keys(match_keys, clause_path_file):
# 处理如'符合本采购文件第一章第二款要求'的情况,跳转到指定地方摘取内容
def process_additional_queries(combined_res, match_keys, output_folder, notice_path, invalid_path):
# print(match_keys)
"""
处理额外的查询并更新结果
@ -340,8 +350,8 @@ def process_additional_queries(combined_res, match_keys, output_folder, notice_p
"""
# 对于空的notice_path的情况此处做了异常处理
clause2_path = convert_clause_to_json(notice_path, output_folder, 2)
updated_match_keys = process_match_keys(match_keys, clause2_path)
new_match_keys = copy.deepcopy(match_keys)
updated_match_keys = process_match_keys(new_match_keys, clause2_path)
if updated_match_keys != match_keys:
form_response_dict = update_json_data(combined_res, updated_match_keys)
else:
@ -372,10 +382,10 @@ def combine_qualification_review(invalid_path, output_folder, qualification_path
"该招标文件中规定的符合性审查标准是怎样的请以json格式给出外层为'符合性审查',你的回答要与原文完全一致,不可擅自总结删减,也不要回答有关资格性审查的内容。"
]
results = multi_threading(user_queries, "", file_id, 2)
combined_res = {}
for _, response in results:
if response:
# print(response)
cleaned_data = clean_json_string(response)
processed = process_dict(preprocess_dict(cleaned_data))
combined_res.update(processed)
@ -391,12 +401,12 @@ def combine_qualification_review(invalid_path, output_folder, qualification_path
file_to_process = qualification_path
combined_res = process_file(file_to_process)
match_keys = find_chapter_clause_references(combined_res, notice_path)
match_keys = find_chapter_clause_references(combined_res)
if not match_keys:
return {"资格审查": combined_res}
return process_additional_queries(combined_res, match_keys, output_folder, notice_path,invalid_path)
return process_additional_queries(combined_res, match_keys, output_folder, notice_path,invalid_path) #还要跳转到第一章
except Exception as e:
print(f"Error in combine_qualification_review: {e}")
@ -407,11 +417,12 @@ def combine_qualification_review(invalid_path, output_folder, qualification_path
# [{'资格性审查.资格要求': '符合本采购文件第一章第二款要求,并提供合格有效的证明材料'}, {'资格性审查.没有重大违法记录的书面声明': '是否提交参加政府采购活动前三年内在经营活动中没有重大违法记录的书面承诺或声明(格式要求详见本项目采购文件第六章相关格式要求)'}]
if __name__ == "__main__":
# qualification_path="C:\\Users\\Administrator\\Desktop\\货物标\\output3\\6.2定版视频会议磋商文件_qualification2.pdf"
output_folder = "C:\\Users\\Administrator\\Desktop\\货物标\\zboutpub"
# qualification_path = "C:\\Users\\Administrator\\Desktop\\货物标\\output3\\094定稿-湖北工业大学轻武器模拟射击设备采购项目招标文件_qualification2.pdf"
qualification_path = ""
notice_path = "C:\\Users\\Administrator\\Desktop\\货物标\\output5\\094定稿-湖北工业大学轻武器模拟射击设备采购项目招标文件_notice.pdf"
output_folder = "D:\\flask_project\\flask_app\\static\\output\\output1\\6558a50a-13ea-4279-a5db-684935481c39\\tmp"
qualification_path = "C:\\Users\\Administrator\\Desktop\\货物标\\output3\\2-招标文件_qualification1.pdf"
# qualification_path = "D:\\flask_project\\flask_app\\static\\output\\output1\\6558a50a-13ea-4279-a5db-684935481c39\\ztbfile_qualification2.pdf"
# notice_path = "D:\\flask_project\\flask_app\\static\\output\\output1\\6558a50a-13ea-4279-a5db-684935481c39\\ztbfile_notice.pdf"
notice_path="C:\\Users\\Administrator\\Desktop\\货物标\\output5\\2-招标文件_notice.pdf"
# knowledge_name = "6.2视频会议docx"
invalid_path = "C:\\Users\\Administrator\\Desktop\\fsdownload\\3395fc1b-432d-407d-a872-fc35e8475aef\\ztbfile_invalid.pdf"
invalid_path = "D:\\flask_project\\flask_app\\static\\output\\output1\\6558a50a-13ea-4279-a5db-684935481c39\\ztbfile.pdf"
res = combine_qualification_review(invalid_path,output_folder, qualification_path, notice_path)
print(json.dumps(res, ensure_ascii=False, indent=4))