242 lines
12 KiB
Python
242 lines
12 KiB
Python
import re
|
||
|
||
data={
|
||
"基础信息": {
|
||
"招标人/代理信息": {
|
||
"招标人": "广水市公安局",
|
||
"招标人联系方式": {
|
||
"名称": "广水市公安局",
|
||
"联系电话": "0722-6248000",
|
||
"地址": "广水市应山办事处应十大道189号"
|
||
},
|
||
"招标代理机构": "湖北楚振捷工程项目管理有限公司",
|
||
"招标代理机构联系方式": {
|
||
"名称": "湖北楚振捷工程项目管理有限公司",
|
||
"联系电话": "0722-6256088",
|
||
"地址": "广水市永阳一路41号"
|
||
},
|
||
"项目联系方式": {
|
||
"名称": "吴凡",
|
||
"联系电话": "18871130808"
|
||
}
|
||
},
|
||
"项目信息": {
|
||
"项目名称": "广水市公安局视频会议高清化改造项目",
|
||
"项目编号": "HBCZJ-2021-CS12",
|
||
"项目概况": "广水市公安局视频会议高清化改造项目",
|
||
"项目基本情况": {
|
||
"项目编号": "HBCZJ-2021-CS12",
|
||
"采购计划备案号": "2021-04-000399",
|
||
"项目名称": "广水市公安局视频会议高清化改造项目",
|
||
"采购方式": "竞争性磋商",
|
||
"预算金额": "192万元",
|
||
"最高限价": "192万元",
|
||
"采购需求": {
|
||
"项目概况及内容": "广水市公安局视频会议高清化改造项目。",
|
||
"招标范围": "广水市公安局视频会议高清化改造项目,具体内容见磋商文件第三章。",
|
||
"项目地点": "具体以合同约定为准。"
|
||
},
|
||
"合同履行期限": "以合同签订为准。",
|
||
"本项目(是/否)接受联合体投标": "否",
|
||
"是否可采购进口产品": "否"
|
||
},
|
||
"招标控制价": "192万元",
|
||
"投标竞争下浮率": "未知",
|
||
"是否允许分包": "未知",
|
||
"是否接受联合体投标": "否"
|
||
},
|
||
"采购要求": {
|
||
"技术要求": "未提供",
|
||
"商务要求": "未提供",
|
||
"服务要求": "未提供",
|
||
"其他要求": "未提供"
|
||
},
|
||
"关键时间/内容": {
|
||
"投标文件递交截止日期": "2021年 6月 18日 15点 00分",
|
||
"投标文件递交地点": "广水市公共资源交易中心五楼 501号开标室",
|
||
"开标时间": "2021年 6月 18日 15点 00分",
|
||
"开标地点": "广水市公共资源交易中心五楼 501号开标室",
|
||
"澄清招标文件的截止时间": "同采购文件获取截止时间(如有)",
|
||
"投标有效期": "90日历天",
|
||
"信息公示媒介": "中国湖北政府采购网:http://www.ccgp-hubei.gov.cn, 中国广水网:http://www.zggsw.gov.cn/"
|
||
},
|
||
"保证金相关": {
|
||
"投标保证金": "不提交",
|
||
"履约保证金": "不提交",
|
||
"是否递交磋商保证金": "否",
|
||
"退还投标保证金": "/",
|
||
"质量保证金": "未知"
|
||
},
|
||
"其他信息": {
|
||
"投标费用承担": "供应商应承担所有与准备和参加磋商有关的费用,不论磋商的结果如何,采购人和采购代理机构均无义务和责任承担这些费用。",
|
||
"招标代理服务费": {
|
||
"收费标准": "根据国家发展与改革委员会办公厅发改办价格【2003】857 号文的规定,经协商由成交供应商按国家发展和改革委员发改价格【2011】534号文规定货物类取费标准向采购代理机构支付招标代理服务费(包含“招标代理费、评标会务费、评标费”),如本项目各包服务费不足叁仟元则供应商按叁仟元支付服务费。",
|
||
"递交方式": "成交服务费由成交供应商在领取成交通知书的同时向代理机构支付,可使用现金或电汇办理,汇款账户信息如下: 账户名:湖北楚振捷工程项目管理有限公司 账户号码:580742561314 开户银行:中国银行股份有限公司广水支行营业部"
|
||
},
|
||
"是否退还投标文件": "否",
|
||
"是否召开投标答疑会": "否",
|
||
"投标预备会": "不召开",
|
||
"踏勘现场": "不组织",
|
||
"偏离": {
|
||
"偏离项要求": "供应商需在响应文件中提供《采购需求响应、偏离说明表/导读表》,具体格式见第六章响应文件格式中的49页。供应商需对采购需求中的各项技术参数和服务要求进行逐项响应,明确表明无偏离、正偏离或负偏离的情况。",
|
||
"正偏离定义": "供应商提供的产品或服务优于采购需求中的技术参数和服务要求。",
|
||
"负偏离定义": "供应商提供的产品或服务未能完全满足采购需求中的技术参数和服务要求。",
|
||
"偏离项处理": "非★号条款允许的负偏离项数及范围见第四章评标办法,★号条款不允许负偏离。",
|
||
"偏离项数量限制": "非★号条款允许的负偏离项数及范围见第四章评标办法,具体数量限制未知。",
|
||
"偏离项评分影响": "负偏离可能会影响供应商的评分,具体评分标准见第四章评定办法。"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
def inner_post_processing(base_info):
|
||
"""
|
||
处理 '基础信息' 部分,提取所需字段。
|
||
|
||
参数:
|
||
base_info (dict): 包含 '基础信息' 的字典。
|
||
|
||
返回:
|
||
dict: 提取的信息字典 extracted_info。
|
||
"""
|
||
# 初始化提取的信息字典
|
||
extracted_info = {}
|
||
|
||
# 定义一个辅助函数用于获取嵌套字典中的值
|
||
def get_nested(dic, keys, default=None):
|
||
for key in keys:
|
||
if isinstance(dic, dict):
|
||
dic = dic.get(key, default)
|
||
else:
|
||
return default
|
||
return dic
|
||
|
||
# 定义一个辅助函数用于递归查找包含特定子字符串的键
|
||
def find_keys_containing(dic, substring):
|
||
found_values = []
|
||
if isinstance(dic, dict):
|
||
for key, value in dic.items():
|
||
if substring in key:
|
||
found_values.append(value)
|
||
if isinstance(value, dict):
|
||
found_values.extend(find_keys_containing(value, substring))
|
||
elif isinstance(value, list):
|
||
for item in value:
|
||
if isinstance(item, dict):
|
||
found_values.extend(find_keys_containing(item, substring))
|
||
return found_values
|
||
|
||
# 定义一个辅助函数用于根据候选键列表提取值(部分匹配)
|
||
def extract_field(contact_info, candidate_keys):
|
||
for candidate in candidate_keys:
|
||
for key, value in contact_info.items():
|
||
if candidate in key and value not in ["未知", ""]:
|
||
return value
|
||
return ""
|
||
|
||
# 定义一个辅助函数用于提取 '投标保证金'
|
||
def extract_bid_bond(guarantee_info):
|
||
# 定义投标保证金的候选键
|
||
bid_bond_candidates = ["投标保证金", "磋商保证金"]
|
||
|
||
# 第一步:查找包含 "投标保证金" 或 "磋商保证金" 的键
|
||
for candidate in bid_bond_candidates:
|
||
for key, value in guarantee_info.items():
|
||
if candidate in key:
|
||
if isinstance(value, dict):
|
||
# 在嵌套字典中查找包含 "金额" 的键
|
||
for sub_key, sub_value in value.items():
|
||
if "金额" in sub_key and sub_value not in ["未知", ""]:
|
||
return sub_value
|
||
elif isinstance(value, str):
|
||
if "金额" in key and value not in ["未知", ""]:
|
||
return value
|
||
else:
|
||
# 如果 value 既不是 dict 也不是 str,忽略
|
||
continue
|
||
|
||
# 第二步:如果没有找到包含 "金额" 的键,尝试在所有键值中查找符合模式的值
|
||
amount_pattern = re.compile(r'(?:\d{1,3}(?:[,,]\d{3})*(?:\.\d+)?|\d+(?:\.\d+)?|[\u4e00-\u9fff]+(?:\.\d+)?)\s*(?:元|万元)')
|
||
for key, value in guarantee_info.items():
|
||
if isinstance(value, str):
|
||
match = amount_pattern.search(value)
|
||
if match:
|
||
return match.group()
|
||
elif isinstance(value, dict):
|
||
# 递归查找嵌套字典中的金额
|
||
found_amount = extract_bid_bond(value)
|
||
if found_amount:
|
||
return found_amount
|
||
# 如果都没有找到,则返回空字符串
|
||
return ""
|
||
|
||
# 定义所需字段的映射关系,暂时不包含'联系人'和'联系电话'以及'招标项目地点'
|
||
mapping = {
|
||
"代理机构名称": [["招标人/代理信息", "招标代理机构"]],
|
||
"招标项目名称": [["项目信息", "项目名称"], ["项目信息", "工程名称"]],
|
||
"招标项目编号": [["项目信息", "项目编号"], ["项目信息", "招标编号"]],
|
||
"开标时间": [["关键时间/内容", "开标时间"]],
|
||
"报名截止日期": [["关键时间/内容", "投标文件递交截止日期"]],
|
||
"招标项目预算": [["项目信息", "招标控制价"]],
|
||
"招标单位名称": [["招标人/代理信息", "招标人"]],
|
||
"招标公告地址": [["关键时间/内容", "信息公示媒介"], ["关键时间/内容", "评标结果公示媒介"]]
|
||
}
|
||
|
||
# 提取并映射字段
|
||
for new_key, paths in mapping.items():
|
||
value = None
|
||
for path in paths:
|
||
value = get_nested(base_info, path)
|
||
if value:
|
||
break
|
||
extracted_info[new_key] = value if value else ""
|
||
|
||
# 特殊处理 '招标项目地点'
|
||
# 在 '项目信息' 下查找包含 "地点" 的键
|
||
project_info = base_info.get("项目信息", {})
|
||
location_candidates = find_keys_containing(project_info, "地点")
|
||
if location_candidates:
|
||
# 选择第一个找到的地点
|
||
extracted_info["招标项目地点"] = location_candidates[0]
|
||
else:
|
||
extracted_info["招标项目地点"] = ""
|
||
|
||
# 特殊处理 '联系人' 和 '联系电话'
|
||
# 提取 '项目联系方式'
|
||
project_contact = get_nested(base_info, ["招标人/代理信息", "项目联系方式"], {})
|
||
|
||
# 提取 '招标人联系方式'
|
||
bidder_contact = get_nested(base_info, ["招标人/代理信息", "招标人联系方式"], {})
|
||
|
||
# 定义候选键列表,按优先级排序
|
||
name_candidates = ["名称", "联系人", "招标"]
|
||
phone_candidates = ["电话", "手机", "联系方式"]
|
||
|
||
# 提取 '联系人'
|
||
contact_names = [project_contact, bidder_contact]
|
||
contact_name = ""
|
||
for contact in contact_names:
|
||
extracted_name = extract_field(contact, name_candidates)
|
||
if extracted_name:
|
||
contact_name = extracted_name
|
||
break
|
||
extracted_info["联系人"] = contact_name
|
||
|
||
# 提取 '联系电话'
|
||
contact_phones = [project_contact, bidder_contact]
|
||
contact_phone = ""
|
||
for contact in contact_phones:
|
||
extracted_phone = extract_field(contact, phone_candidates)
|
||
if extracted_phone:
|
||
contact_phone = extracted_phone
|
||
break
|
||
extracted_info["联系电话"] = contact_phone
|
||
|
||
# 特殊处理 '投标保证金'
|
||
# 提取 '保证金相关'
|
||
guarantee_info = get_nested(base_info, ["保证金相关"], {})
|
||
extracted_info["投标保证金"] = extract_bid_bond(guarantee_info)
|
||
|
||
return extracted_info
|
||
|
||
res=inner_post_processing(data["基础信息"])
|
||
print(res) |