瀏覽代碼

修复角色金额、字典匹配;规则补充表头

lsm 3 周之前
父節點
當前提交
b18eb0fb70

+ 3 - 1
BiddingKG/dl/common/Utils.py

@@ -1160,7 +1160,7 @@ def get_money_entity(sentence_text, found_yeji=0, in_attachment=False):
     # 使用正则识别金额
     entity_type = "money"
     list_money_pattern = {"cn": "(()(?P<filter_kw>百分之)?(?P<money_cn>[零壹贰叁肆伍陆柒捌玖拾佰仟萬億圆十百千万亿元角分]{3,})())",
-                          "key_word": "((?P<text_key_word>(?:[¥¥]+,?|(中标|成交|合同|承租|投资|服务))?(金?额|价格?)|价格|预算(金额)?|(监理|设计|勘察)(服务)?费|[单报标限总造]价款?|金额|租金|标的基本情况|CNY|成交结果|资金|(控制|拦标)价|投资|成本)(\d:|\d=\d[-+×]\d:)?(?:[,,\[(\(]*\s*(人民币|单位:?)?/?(?P<unit_key_word_before>[万亿]?(?:[美日欧]元|元(/(M2|[\u4e00-\u9fa5]{1,3}))?)?(?P<filter_unit2>[台个只吨]*))\s*(/?费率)?(人民币)?[\])\)]?)\s*[,,::]*(RMB|USD|EUR|JPY|CNY)?[::]?(\s*[^壹贰叁肆伍陆柒捌玖拾佰仟萬億分万元编号时间日期计采a-zA-Z]{,8}?))(第[123一二三]名[::])?(\d+(\*\d+%)+=)?(?P<money_key_word>\d+,\d+\.\d{2,6}|\d{1,3}([,,]\d{3})+(\.\d+)?|\d+(\.\d+)?[百千]{,1})(?P<science_key_word>(E-?\d+))?(?:[(\(]?(?P<filter_>[%%‰折])*\s*,?((金额)?单位[::])?(?P<unit_key_word_behind>[万亿]?(?:[美日欧]元|元)?(?P<filter_unit1>[台只吨斤棵株页亩方条天年月日]*))\s*[)\)]?))",
+                          "key_word": "((?P<text_key_word>(?:[¥¥]+,?|(中标|成交|合同|承租|投资|服务|起始))?(金?额|价格?)|价格|预算(金额)?|(监理|设计|勘察)(服务)?费|[单报标限总造]价款?|金额|租金|标的基本情况|CNY|成交结果|资金|(控制|拦标)价|投资|成本)(\d:|\d=\d[-+×]\d:)?(?:[,,\[(\(]*\s*(人民币|单位:?)?/?(?P<unit_key_word_before>[万亿]?(?:[美日欧]元|元(/(M2|[\u4e00-\u9fa5]{1,3}))?)?(?P<filter_unit2>[台个只吨]*))\s*(/?费率)?(人民币)?[\])\)]?)\s*[,,::]*(RMB|USD|EUR|JPY|CNY)?[::]?(\s*[^壹贰叁肆伍陆柒捌玖拾佰仟萬億分万元编号时间日期计采a-zA-Z]{,8}?))(第[123一二三]名[::])?(\d+(\*\d+%)+=)?(?P<money_key_word>\d+,\d+\.\d{2,6}|\d{1,3}([,,]\d{3})+(\.\d+)?|\d+(\.\d+)?[百千]{,1})(?P<science_key_word>(E-?\d+))?(?:[(\(]?(?P<filter_>[%%‰折])*\s*,?((金额)?单位[::])?(?P<unit_key_word_behind>[万亿]?(?:[美日欧]元|元)?(?P<filter_unit1>[台只吨斤棵株页亩方条天年月日]*))\s*[)\)]?))",
                           "front_m": "((?P<text_front_m>(?:[(\(]?\s*(?P<unit_front_m_before>[万亿]?(?:[美日欧]元|元))\s*[)\)]?)\s*[,,::]*(\s*[^壹贰叁肆伍陆柒捌玖拾佰仟萬億分万元编号时间日期计采a-zA-Z金额价格]{,2}?))(?P<money_front_m>\d{1,3}([,,]\d{3})+(\.\d+)?|\d+(\.\d+)?(?:,?)[百千]*)(?P<science_front_m>(E-?\d+))?())",
                           "behind_m": "(()()(?P<money_behind_m>\d{1,3}([,,]\d{3})+(\.\d+)?|\d+(\.\d+)?(?:,?)[百千]*)(?P<science_behind_m>(E-?\d+))?(人民币)?[\((]?(?P<unit_behind_m>[万亿]?(?:[美日欧]元|元)(?P<filter_unit3>[台个只吨斤棵株页亩方条米]*))[\))]?)"}
     # 2021/7/19 调整金额,单位提取正则,修复部分金额因为单位提取失败被过滤问题。  20240415 调整front_m 修复 详见合同元,合同金额:378.8万元 提取
@@ -1334,6 +1334,8 @@ def get_money_entity(sentence_text, found_yeji=0, in_attachment=False):
             elif re.search('^[/每]', sentence_text[_match.end():]):
                 # print('单价:', _match.group(0))
                 notes = '单价'
+            elif re.search('单价', sentence_text[max(0, _match.start()-10):_match.start()]):
+                notes = '单价'
             elif re.search('[零壹贰叁肆伍陆柒捌玖拾佰仟萬億圆]', entity_text) != None:
                 notes = '大写'
                 if entity_text[0] == "拾":  # 2021/12/16 修正大写金额省略了数字转换错误问题

+ 11 - 6
BiddingKG/dl/entityLink/entityLink.py

@@ -14,8 +14,6 @@ from BiddingKG.dl.interface.Entitys import *
 import json
 from BiddingKG.dl.common.constDict import ConstDict
 
-business_dic = {}
-
 def edit_distance(source,target):
     dp = [["" for i in range(len(source)+1)] for j in range(len(target)+1)]
     for i in range(len(dp)):
@@ -152,6 +150,7 @@ def get_role(dic):
     return 5, 0
 
 def link_entitys(list_entitys,on_value=1):#on_value=0.81
+    business_dic = {}
     for list_entity in list_entitys:
         range_entity = []
         short_entity = []  # 不包含工商数据实体
@@ -297,6 +296,7 @@ def get_nlp_enterprise(list_entity):
     nlp_enterprise = []
     nlp_enterprise_attachment = []
     dict_enterprise = {}
+    business_dic = {}
     max_num = 100
     list_entity = sorted(list_entity,key=lambda x:(x.sentence_index,x.begin_index))
     for entity in list_entity:
@@ -516,7 +516,7 @@ load_enterprise_thread.start()
 
 MAX_ENTERPRISE_LEN = 30
 
-def match_enterprise_max_first(sentence):
+def match_enterprise_max_first(sentence, business_dic):
     while True:
         if not DICT_ENTERPRISE_DONE:
             time.sleep(1)
@@ -560,10 +560,14 @@ def match_enterprise_max_first(sentence):
                         if enter_tail in SET_TAIL_ENTERPRISE or re.search('(中心|中学|小学|医院|学院|大学|学校|体校|监狱|大队|支队|林场|海关|分局|商行)$', enter_tail):
                             if fix_name not in business_dic:
                                 have_bus, dic = get_business_data(fix_name) # 20210124 改为有工商数据的实体才添加
+                                if have_bus == False and 'have_business' in dic and re.search('^(上海|云南|内蒙古|北京|吉林|四川|天津|宁夏|安徽|山东|山西|广东|广西|新疆|江苏|江西|河北|河南|浙江|海南|湖北|湖南'
+                                    '|甘肃|福建|西藏|贵州|辽宁|重庆|陕西|青海|黑龙江|\w{1,5}[市县])[\w()]{2,15}[厂店铺市场行部城室馆中心站处社会狱所园关局司署段厅院队小学]$',fix_name): # 无工商数据有前面地址后面有关键词且在字典表的添加
+                                    have_bus = True
+                                    log('字典表补充无工商数据有关键词实体:%s'%fix_name)
                                 business_dic[fix_name] = (have_bus, dic)
                             else:
                                 have_bus, dic = business_dic.get(fix_name) # 20240708 字典保存查询过的工商数据,避免重复查询redis
-                            if have_bus or (re.search('(中心|中学|小学|医院|学院|大学|学校|体校|监狱|大队|支队|林场|海关|分局|商行)$', enter_tail) and is_enterprise_exist(fix_name)):
+                            if have_bus:
                             # if is_enterprise_exist(enter_name):
                                 match_item = {"entity_text":"%s"%(fix_name),"begin_index":begin_index,"end_index":begin_index+len(enter_name)}
                                 # print("match_item",key_enter,enter_name)
@@ -574,7 +578,7 @@ def match_enterprise_max_first(sentence):
             else:
                 break
     # print("======",list_match)
-    not_match_names = ['乌鲁木齐经济技术开发区(乌鲁木齐市头屯河区)市场监督管理局(区知识产权局、区市场监管综合行政执法队)', '政采云有限公司'] # 字典匹配不到的名称列表
+    not_match_names = ['乌鲁木齐经济技术开发区(乌鲁木齐市头屯河区)市场监督管理局(区知识产权局、区市场监管综合行政执法队)', '政采云有限公司', '徽县发展和改革局', '徽县以工代赈易地搬迁办公室'] # 字典匹配不到的名称列表
     pattern = re.compile('|'.join(not_match_names))
     for it in re.finditer(pattern, sentence):
         match_item = {"entity_text": "%s" % (it.group(0)), "begin_index": it.start(), "end_index": it.end()}
@@ -583,6 +587,7 @@ def match_enterprise_max_first(sentence):
     return list_match
 
 def calibrateEnterprise(list_articles,list_sentences,list_entitys):
+    business_dic = {}
     for _article,list_sentence,list_entity in zip(list_articles,list_sentences,list_entitys):
         list_calibrate = []
         match_add = False
@@ -596,7 +601,7 @@ def calibrateEnterprise(list_articles,list_sentences,list_entitys):
         for p_sentence in list_sentence:
             sentence = p_sentence.sentence_text
             sentence_entitys = [(ent.entity_text,ent.wordOffset_begin,ent.wordOffset_end) for ent in list_entity if ent.sentence_index==p_sentence.sentence_index and ent.entity_type in ['org','company']]
-            list_match = match_enterprise_max_first(sentence)
+            list_match = match_enterprise_max_first(sentence, business_dic)
             # print("list_match", list_match)
 
             doc_id = p_sentence.doc_id

+ 4 - 1
BiddingKG/dl/interface/Preprocessing.py

@@ -716,7 +716,10 @@ def tableToText(soup, docid=None, return_kv=False):
                 inner_table[i][j] = [origin_inner_table[i][j][0], int(predict_list[i][j])]
                 if origin_inner_table[i][j][0] in ['主要环境影响及预防或者减轻不良环境影响的对策和措施', '建设单位或地方政府作出的相关环保承诺',
                                                    '公众反馈意见的联系方式', '区县', '项目领域', '成本/收入', '覆盖倍数', '会计所', '律所','建设期',
-                                                   "发行时间" ,"批次" ,"发行额" ,"发行利率" ,"所属债券" ,"专项债作资本金发行额" ,"调整记录"] and predict_list[i][j]!=1:
+                                                   "发行时间" ,"批次" ,"发行额" ,"发行利率" ,"所属债券" ,"专项债作资本金发行额" ,"调整记录","资产面积",
+                                                   "交易底价","交易地点"] and predict_list[i][j]!=1:
+                    inner_table[i][j] = [origin_inner_table[i][j][0], 1]
+                elif predict_list[i][j]!=1 and re.search('^(中标|中选|成交|(参与)?投标|招标|采购|招租)(单位|人)$|^(中标|中选|成交)(金额|价格)$', origin_inner_table[i][j][0]):
                     inner_table[i][j] = [origin_inner_table[i][j][0], 1]
                 elif origin_inner_table[i][j][0] in ['经评审的最低评标价法'] and predict_list[i][j]==1:
                     inner_table[i][j] = [origin_inner_table[i][j][0], 0]

+ 1 - 1
BiddingKG/dl/interface/extract.py

@@ -529,7 +529,7 @@ def predict(doc_id,text,title="",page_time="",web_source_no='',web_source_name="
 
     # data_res = Preprocessing.union_result(Preprocessing.union_result(codeName, prem),list_punish_dic)[0]
     # data_res = Preprocessing.union_result(Preprocessing.union_result(Preprocessing.union_result(codeName, prem),list_punish_dic), list_channel_dic)[0]
-    version_date = {'version_date': '2025-04-23'}
+    version_date = {'version_date': '2025-05-15'}
     data_res = dict(codeName[0], **prem[0], **channel_dic, **product_attrs[0], **product_attrs[1], **payment_way_dic, **fail_reason, **industry, **district, **candidate_dic, **version_date, **all_moneys, **pb_json)
 
     if original_docchannel == 302:

+ 2 - 2
BiddingKG/dl/interface/modelFactory.py

@@ -87,9 +87,9 @@ class Model_role_classify_word():
         :param text:
         :return:
         '''
-        text = re.sub('第[一二三1-3]([条项章]|中学|医院|附属)|第三方(服务机构)?', 'xxx', text)
+        text = re.sub('第[一二三1-3]([条项章]|中学|医院|附属)|第三方(服务机构)?|(中标|成交|中选)(候选|结果)?(单位|人)?公[示告]', 'xxx', text)
         text = re.sub('第01(中标|成交)?候选人', '第一中标候选人', text)
-        text = re.sub('(标[段的包项]|品目)[一二三1-3]', '标段', text)
+        text = re.sub('(标[段的包项]?|品目)[一二三1-3]', '标段', text)
         text = re.sub('第?[一二三1-3](标段?|[分子标]?包)', 'd标段', text)
         text = re.sub('[a-zA-Z][a-zA-Z0-9=&_—-]{3,}', 'abc', text)
         text = re.sub('[【(\[][0-9]{2,}[\])】]|\d+([::.-]\d+)+', 'd', text)

+ 1 - 1
BiddingKG/dl/interface/outline_extractor.py

@@ -91,7 +91,7 @@ def extract_parameters(parse_document):
         # print(_data.keys())
         if _type=="sentence":
             if _data["sentence_title"] is not None:
-                if re.search('[((][一二三四五六七八九十}]+[))]|[一二三四五六七八九十]+\s*、|^\d{1,2}[.、][\u4e00-\u9fa5]', _text[:10]):
+                if re.search('[((][一二三四五六七八九十}]+[))]|[一二三四五六七八九十]+\s*[..]|^\d{1,2}[.、][\u4e00-\u9fa5]', _text[:10]):
                     idx = _text.replace(':', ':').find(':')
                     outline_text = _text[:idx] if idx >= 4 else _text
                     out_lines.append((outline_text, _data['sentence_index'], _data['wordOffset_begin']))

+ 25 - 11
BiddingKG/dl/interface/predictor.py

@@ -875,7 +875,7 @@ class PREMPredict():
             elif label in [2,3,4] and re.search('序号:\d+,\w{,2}候选', front):
                 label = 5
             elif label == 0:
-                if re.search('拟邀请$|受邀谈判方', front):
+                if re.search('拟邀请$|受邀谈判方|流入方名称:$', front):
                     label = 2
                     values[label] = 0.501
                 elif re.search('(发布(人|方|单位|机构|组织|用户|业主|主体|部门|公司|企业)|组织(单位|人|方|机构)?|(采购|招标|发布)机构)(名称)?[是为:]+', front) and is_agency(entity.entity_text):
@@ -918,7 +918,7 @@ class PREMPredict():
                     label = 5
                 elif re.search('(承包权人|帐户名称|债务人|推荐预审合格投标人名单):$|确定为标的的受让方,$|[主次出]入口?,?$|确定(项目|\w{,2})成交供应商,$|,承刻单位:$|乙方接受为$|丙方:$|来源名称:$', front):  # 234501112 民币元,序号:1,债务人: 东营市海宁工贸有限责任公司 ,债权本金: 262414286 八、中标后签约单位,合同签约单位: 241929628 1月9,承刻单位: 肃宁县超凡网络光敏印章刻印部 ,印章预留印模  600825761 来源名称:红星集团,评标时间:
                     label = 5
-                elif re.search('来源:$', front) and re.search('^,', behind): # 修复 472062585 项目采购-关于定制手机询比价采购中标公告,来源:深圳市网联安瑞网络科技有限公司 预测为中标
+                elif re.search('来源(单位)?:$', front):# and re.search('^,', behind): # 修复 472062585 项目采购-关于定制手机询比价采购中标公告,来源:深圳市网联安瑞网络科技有限公司 预测为中标
                     label = 0
                     values[label] = 0.5
                 elif re.search('合同供方:?$|合同签约单位', front):
@@ -936,6 +936,11 @@ class PREMPredict():
                 elif re.search('^为\w{,10}第二(成交|中标)单位', behind): # 中标预测错误,例:601143888 河南省创慧新材料科技有限公司为铸咀采购项目第二成交单位
                     label = 3
                     values[3] = 0.5
+                elif re.search('中标单位,$', front):
+                    label = 5
+                elif re.search('^为预备中标单位', behind):
+                    label = 3
+                    values[3] = 0.5
             elif re.search('是否中标:是,供应商', front) and label == 5:
                 label = 2
                 values[label] = 0.9
@@ -961,6 +966,8 @@ class PREMPredict():
                 elif re.search('推荐入围的招标代理单位:$', front): # 20240709 修复302505502预测错为代理
                     label = 2
                     values[label] = 0.501
+                elif re.search('代理公司$', front) and re.search('^销售', behind): # 修复 103462671 且该软件平台由博导前程软件公司在浙江的官方代理公司杭州楚沩教育科技有限公司销售。
+                    label = 5
             elif label in [3,4]:
                 if re.search('第[二三]分(公司|店),中标(人|供应商|单位|公司):$', front):
                     label = 2
@@ -974,13 +981,13 @@ class PREMPredict():
                 elif re.search('\d+\.\d+[,、]?(中标|成交)候选人|[;,][23]、(中标|中选|成交)候选人:', front):
                     label = 5
                     values[label] = 0.501
-                elif re.search('第一名:$', front):
+                elif re.search('第一名:$|[二三23][,、](中标|成交|中选)(单位|人|供应商):$|成交供应商为$', front): # 108505049 一,招租单位:井都神山经联社。二,成交单位:广东新潮建设有限公司。
                     label = 2
                     values[label] = 0.7
             elif re.search('(中标|成交)通知书[,:]$', front) and re.search('^:', behind) and label != 2:
                 label = 2
                 values[label] = 0.8
-            elif label==5 and re.search('^拟(招标|采购)一批|^须购置一批', front):
+            elif label==5 and re.search('^拟(招标|采购)一批|^须购置一批', behind):
                 label = 0
                 values[label] = 0.7
             entity.set_Role(label, values)
@@ -1486,7 +1493,7 @@ class RoleRulePredictor():
                "(乙|竞得|受让|买受|签约|供货|供应?|合作|承做|承包|承建|承销|承保|承接|承制|承担|承修|承租((包))?|入围|入选|竞买)(候选|投标)?(人|单位|机构|供应商|方|公司|企业|厂商|商|社会资本方?|银行)(:?单位名称|:?名称|盖章)?[::是为]+$" \
                "|(选定单位|指定的中介服务机构|实施主体|中标银行|中标通知书,致|征集结果|选择中介|选择结果|成交对象|勘察人|(,|审计|处置|勘察|设计)服务单位|受托[人方])[::是为]+$" \
                "|((评审结果|名次|排名|中标结果)[::]*第?[一1]名?)[::是为]+$|成交供应商信息[,:]?(序号1)?:?|供应商名称$|竞争性选择申请人名称:$" \
-               "|单一来源(采购)?(供应商|供货商|服务商|方式向)$|((中标|成交)(结果|信息))[::是为]+$|(中标|成交)供应商、(中标|成交)(金额|价格),$|合作伙伴名称:$|供应商(乙方)-?$" \
+               "|单一来源(采购)?(供应商|供货商|服务商|方式向)$|((中标|成交)(结果|信息))[::是为]+$|(中标|成交)供应商、(中标|成交)(金额|价格),$|合作伙伴名称:$|供应商(乙方)-?$|合作单位:$" \
                "|现(公布|宣布|公示)中标单位如下:$|现将中标单位(公布|公示)如下:$|现宣布以下(企业|单位|公司)中标:$|经讨论,决定采用$|第\d+(包件?|标段?)(中标|中选|成交)候选人:$|入围供应商如下(排名不分先后)[,:]$)"  # 承办单位:不作为中标 83914772  |施工 单位不作为中标人 例:386692187
         self.pattern_winTenderer_left_60 = "(?P<winTenderer_left_60>" \
                                            "(,|。|:|^)((中标(投标)?|[拟预]中标|中选|中价|中签|成交)(人|单位|机构|中介(服务)?机构|供应商|客户|方|公司|企业|厂商|商家?|社会资本方?|银行)|(中标候选人)?第?[一1]名|第[一1](中标|中选|成交)?候选人|服务机构)" \
@@ -1498,7 +1505,7 @@ class RoleRulePredictor():
         self.pattern_winTenderer_right = "(?P<winTenderer_right>(^[是为](首选)?((采购|中标|成交)(供应商|供货商|服务商)|(第[一1]|预)?(拟?(中标|中选|中价|成交)(候选|排序)?(人|单位|机构|供应商|公司|企业|厂商|银行)))|" \
                                          "^((报价|价格)最低,|以\w{5,10})?(确定|成|作)?为[\w“”()]{3,25}((成交|中选|中标|服务)(人|单位|供应商|企业|公司)|供货单位|供应商|第一中标候选人)[,。]" \
                                          "|^:贵公司参与|^:?你方于|^(胜出)?(中标|成交)[,。]|^取得中标(单位)?资格|^以\d+[\d,.]+万?元(中标|成交|中选)" \
-                                         "|^通过(挂牌|拍卖)方式(以[\d.,]+万?元)?竞得|^[((](中标|成交|承包)人名?称?[))]))" # 去掉 |\w{,20} 修复 460216955 网上公布的与本次采购项目有关的信息视为已送达各响应供应商。 作为中标
+                                         "|^通过(挂牌|拍卖)方式(以[\d.,]+万?元)?竞得|^[((](中标|成交|承包)人名?称?[))])|^确定为(中标|成交|中选)人)" # 去掉 |\w{,20} 修复 460216955 网上公布的与本次采购项目有关的信息视为已送达各响应供应商。 作为中标
         self.pattern_winTenderer_whole = "(?P<winTenderer_center>(贵公司|由).{,15}以\w{,15}中标|确定[\w()]{5,20}为[^,。;]{5,50}的?中标单位" \
                                          "|选定报价最低的[“”\w()]{5,25}为[^,。;]{5,50}的?(服务|中标|成交)单位" \
                                          "|拟邀请[\w()]{5,20}(进行)?单一来源谈判|(承办单位|报价人|投标人|中介机构)(名称)?:[\w()]{5,20},(中标|承办|中选)(价格|金额)" \
@@ -1539,7 +1546,7 @@ class RoleRulePredictor():
 
         self.SET_NOT_TENDERER = set(["人民政府","人民法院","中华人民共和国","人民检察院","评标委员会","中国政府","中国海关","中华人民共和国政府"])
         
-        self.pattern_money_tenderee = re.compile("投?标?最高限价|采购计划金额|项目预算|招标金额|采购金额|项目金额|投资估算|采购(单位|人)委托价|招标限价|拦标价|预算金额|标底|总计|限额|资金来源,?[为:]+\w{2,4}资金|采购成本价|总费用约?为|(招标|采购)总?(规模|额度|资金)|资金来源|合同价暂定")  # |建安费用 不作为招标金额
+        self.pattern_money_tenderee = re.compile("投?标?最高限价|采购计划金额|项目预算|招标金额|采购金额|项目金额|投资估算|采购(单位|人)委托价|招标限价|拦标价|预算金额|标底|总计|限额|资金来源,?[为:]+\w{2,4}资金|采购成本价|总费用约?为|(招标|采购)总?(规模|额度|资金)|资金来源|合同价暂定|包合计:$")  # |建安费用 不作为招标金额
         self.pattern_money_tenderer = re.compile("((合同|成交|中标|应付款|交易|投标|验收|订单)[)\)]?(综合)?(总?金额|结果|[单报总]?价))|标的基本情况|承包价|报酬(含税):|经评审的价格|报价不?含税")  # 单写 总价 不能作为中标金额,很多表格有单价、总价
         self.pattern_money_tenderer_whole = re.compile("(以金额.*中标)|中标供应商.*单价|以.*元(报价)?(中标|中选|成交)")
         self.pattern_money_other = re.compile("代理费|服务费")
@@ -1603,7 +1610,7 @@ class RoleRulePredictor():
             _label = 5
         elif _label == 2 and re.search('评委|未中标', after[:5]): # 397194341 过滤掉错误召回中标人
             _label = 5
-        elif _label == 2 and re.search('^,?(投标报价|(资格性审查:|符合性审查:)?(不通过|不符合))', after) and re.search('中标|成交|中选|排名|排序|名次|第[一1]名', before[-10:])==None: #20240705 处理类似 493939047 错误
+        elif _label == 2 and re.search('[^\w]供应商', before[-10:]) and re.search('^,?(投标报价|(资格性审查:|符合性审查:)?(不通过|不符合))', after[:12]) and re.search('中标|成交|中选|排名|排序|名次|第[一1]名', before[-10:])==None: #20240705 处理类似 493939047 错误
             _label = 5
         if _label == 5:
             _label, _prob, keyword = self.ser_role(self.pattern_whole, before + center + after, entity_text)  # 前后文匹配
@@ -1810,7 +1817,7 @@ class RoleRulePredictor():
                                     break
                                 if re.search(self.candidate_left, before) and re.search('尊敬的|各', before[-10:])==None:
                                     candidates.append(p_entity)
-                                elif channel_dic['docchannel']['docchannel'] in ['中标信息', '候选人公示', '合同公告'] and re.search(':$', before) and re.search('^[,。]', after) and re.search('候选人', before): # 补充 577756336 候选人,三期A160、A166地块:中国建设银行成都第九支行,
+                                elif channel_dic['docchannel']['docchannel'] in ['中标信息', '候选人公示', '合同公告'] and re.search(':$', before) and re.search('^[,。]', after) and re.search('候选人', before[-15:]): # 补充 577756336 候选人,三期A160、A166地块:中国建设银行成都第九支行,
                                     candidates.append(p_entity)
 
                                 # # 使用正则+距离解决冲突
@@ -6915,7 +6922,7 @@ class TablePremExtractor(object):
                     if re.search('评分|得分|分数|分值', text):
                         continue
                     if re.search(v, text):
-                        if k in ['tenderer'] and re.search('是否', text):
+                        if k in ['tenderer'] and re.search('是否|未', text): # 修复103367444 未中标单位名称 作为中标
                             continue
                         if k == 'budget' and re.search('量', text): # 预算工作量 预算采购量 等不作为预算
                             continue
@@ -7823,6 +7830,11 @@ class WebsourceTenderee():
             web_ree = '航空总医院'
         if web_ree == "" and re.search('\w{2,8}(大学|医院|妇幼保健院)$', web_source_name): # 20240524 大学、医院类站源没唯一招标人默认为站源名称
             web_ree = web_source_name
+        if web_source_no in ['DX013230-2', 'DX008427-1', 'DX001298', 'DX013230-3', 'DX003960-1', 'DX002797-1', 'DX010532',
+                             'DX014075', 'DX002897', 'DX001242-1', 'DX000545', 'DX001069', 'DX009895', 'DX003270', 'DX006310-1',
+                             '02215-1', 'DX000820', 'DX002512-1', 'DX000443', 'DX008157', 'DX004927', 'DX005403', 'DX001425-1',
+                             'DX000980', 'DX013748-1', 'DX002488', '07056-4', 'XX2102']: # 统计分析可能有问题的唯一招标人
+            web_ree = ''
         if web_ree != '':
             if 'Project' in prem[0]['prem']:
                 find_tenderee = False
@@ -8616,7 +8628,7 @@ class EntityTypeRulePredictor():
         self.pattern_addr_bidsend = '((\w{,4}文件)?(提交|递交)(\w{,4}文件)?|投标)地[点址区]([((]网址[))])?[:为]'
         self.pattern_addr_delivery = '(交货|交付|收货|提货|交接|送货(安装)?|送达|到货|供货|卸货)((期|时间)[及和、])?)?(地[点址区]?|区域)[:为]'
         self.pattern_addr_project = '(项目|施工|实施|建设|工程|服务|展示|看样|拍卖)(实施|服务|现场)?(地[点址区]|位置|所在地区?)(位于)?[:为]|项目位于|[^\w]所[属在](区域|地区?):|存放地[点址]?[:为]' # 银行所属区域:北京市西城区 不作项目地址
-        self.pattern_addr_contact = '(联系|收件人?|邮寄)地[点址区][:为]|行政区:'
+        self.pattern_addr_contact = '((联系|收件人?|邮寄)地[点址区]|行政区)[为]'
         self.pattern_time_planned = '(计划|预计|预期)(招标|采购|发标|发包)时间|招标(公告|文件)(预计|预期|计划)发布时间'
         self.pattern_code_investment = '投资(审批)?项目[编代]码[:为]'
         self.pattern_addr_dic = {'addr_bidopen': self.pattern_addr_bidopen,
@@ -8634,6 +8646,8 @@ class EntityTypeRulePredictor():
                 s_index = entity.sentence_index
                 sentance_text = list_sentences[0][s_index].sentence_text
                 for k, v in self.pattern_addr_dic.items():
+                    if k == 'addr_contact' and re.search('中标|成交|中选|代理|供应商', sentance_text[max(0, b-12):]):
+                        continue
                     v = v.replace('[:为]', '')
                     if re.search(v, sentance_text[max(0, b-10): b]) and len(entity.entity_text)>2:
                         addr_dic[k] = entity.entity_text