From ff1c0e890c4bb7d26a53f095f180b841887a3a89 Mon Sep 17 00:00:00 2001 From: yujj128 Date: Sat, 6 Dec 2025 11:19:09 +0800 Subject: [PATCH] =?UTF-8?q?=E7=AE=80=E5=8E=86=E6=8F=90=E5=8F=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- requirements.txt | 1 + .../parse_resume2_doc.py | 92 +++++++++++++++---- 2 files changed, 75 insertions(+), 18 deletions(-) rename parse_resume2_doc.py => service/parse_resume2_doc.py (79%) diff --git a/requirements.txt b/requirements.txt index 8d3d38b..a9fa245 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,6 +2,7 @@ python-docx fastapi uvicorn docxtpl +python-multipart PyMuPDF>=1.23.0 paddlepaddle>=2.5.0 paddleocr>=2.7.0.3 diff --git a/parse_resume2_doc.py b/service/parse_resume2_doc.py similarity index 79% rename from parse_resume2_doc.py rename to service/parse_resume2_doc.py index 6f0978c..f6aa705 100644 --- a/parse_resume2_doc.py +++ b/service/parse_resume2_doc.py @@ -97,7 +97,14 @@ class EnhancedDocxExtractor: value = self._find_value_for_key(table, structure, row_idx, col_idx, visited, kv_pairs) if value: key = self._normalize_key(cell['text']) - kv_pairs.append((key, value)) + found = False + kv_pairs = [(k,v+","+value)if k == cell['text'] else (k, v) for k,v in kv_pairs ] + for i, (k,v) in enumerate(kv_pairs): + if k == cell['text']: + kv_pairs[i] = (k,value) + found = True + if not found: + kv_pairs.append((key, value)) else: print("不是key") @@ -110,8 +117,17 @@ class EnhancedDocxExtractor: # 尝试右侧单元格 if key_col + 1 < len(structure[key_row]): value_cell = structure[key_row][key_col + 1] + current_key_cell = structure[key_row][key_col] if value_cell['is_key']: return None + # 特殊处理学历 + spec_coll = ['全日制教育','在职教育'] + if current_key_cell['text'].replace('\n','') in spec_coll : + if not value_cell['text']: + value_cell['text'] = 'False' + else: + value_cell['text'] = 'True' + if value_cell['text'] and (key_row, key_col + 1) not in visited: # 检查这个值是否与前一个键提取的值相同(可能是合并单元格) if not self._is_key_duplicate_merged_cell(structure[key_row][key_col]['text'], kv_pairs): @@ -119,6 +135,13 @@ class EnhancedDocxExtractor: print(f"visited add {key_row} {key_col + 1}") visited.add((key_row, key_col + 1)) return value_cell['text'] + else: + current_key = structure[key_row][key_col]['text'] + print(f"key值重复------------------------------key {current_key}") + for key, value in kv_pairs: + if key == current_key: + return value+","+value_cell['text'] + # 尝试下方单元格 if key_row + 1 < len(structure): @@ -165,14 +188,20 @@ class EnhancedDocxExtractor: return False + def extract_parentheses_content(self, text): + # 使用正则表达式提取括号内的所有内容 + matches = re.findall(r'[((]([^))]*)[))]', text) + + return matches # 返回列表,可能包含多个括号 + def _is_likely_key(self, text: str) -> bool: """判断文本是否可能是键""" if not text or len(text) > 20: return False # 检查是否包含常见字段词 - key_indicators = ['籍贯','籍 贯','政治面貌','政治\n面貌','姓名','性别','姓 名', '性 别', '出生年月', '民族','民 族', '单位', '部门','联系地址','主要学习经历', - '职务','职 务','职\n务', '职称','职 称', '电话', '地址', '学历', '学位','现任职务','职业资格','奖惩情况' + key_indicators = ['籍贯','籍 贯','政治面貌','政治\n面貌','姓名','性别','姓 名', '性 别', '出生年月', '民族','民 族', '单位', '部门','联系地址','主要学习经历','全日制教育','在职教育', + '职务','职 务','职\n务', '职称','职 称', '电话', '地址', '学历', '学位','现任职务','职业资格','奖惩情况(近三年主要奖惩信息)' '专业', '岗位', '经历', '时间', '资格','现任职单位及部门','身份证号','婚姻状况','健康状况','应聘岗位','应聘部门/岗位','毕业院校系及专业'] for indicator in key_indicators: @@ -188,6 +217,30 @@ class EnhancedDocxExtractor: if any(indicator in key_part for indicator in key_indicators): return True + for indicator in key_indicators: + print("indicator is ===============================", indicator) + print("text is ===============================", text) + translation_table = str.maketrans('', '', ' \t\n\r\f\v') + indicator = indicator.translate(translation_table) + text = text.translate(translation_table) + clean_text = self.extract_parentheses_content(text) + print(text) + clean_indicator = self.extract_parentheses_content(indicator) + print(indicator) + if not clean_text: + print("特殊匹配失败") + return False + if clean_indicator: + print("开始匹配=========") + clean_text = clean_text[0] + clean_indicator = clean_indicator[0] + if clean_indicator in clean_text: + print(f"特殊情况匹配成功======={text}") + return True + else: + print("继续匹配") + continue + return False def _is_likely_value(self, text: str) -> bool: @@ -225,10 +278,10 @@ class EnhancedDocxExtractor: def _categorize_field(self, key: str) -> str: """将字段分类""" categories = { - '基本信息': ['姓名', '性别', '出生年月', '民族', '政治面貌','学历学位','毕业院校系及专业' - '婚姻状况', '健康状况', '籍贯', '身份证号','联系电话','婚姻状况','健康状况','身份证号','联系电话(手机)','毕业院校系及专业','联系地址','主要学习经历','奖惩情况'], + '基本信息': ['姓名', '性别', '出生年月', '民族', '政治面貌','学历学位','毕业院校系及专业','全日制教育','在职教育' + '婚姻状况', '健康状况', '籍贯', '身份证号','联系电话','婚姻状况','健康状况','身份证号','联系电话(手机)','毕业院校系及专业','联系地址','主要学习经历','奖惩情况(近三年主要奖惩信息)'], '工作信息': ['现任职单位及部门', '现任职务', '职称', '职业资格', - '参加工作时间', '职称取得时间','应聘部门/岗位','是否接受调剂职级/岗位'], + '参加工作时间', '职称取得时间','应聘部门/岗位','是否接受调剂职级/岗位','奖惩情况(近三年主要奖惩信息)'], } for category, fields in categories.items(): @@ -287,9 +340,9 @@ def quick_extract(docx_path: str): base_map = ['姓名','性别','籍贯','政治面貌','出生年月','身份证号','现居住地','民族','学历','学位','学历学位','特长','联系电话','联系电话(手机)', - '婚姻状况','健康状况','毕业院校系及专业','主要学习经历','联系地址','入党/团时间'] + '婚姻状况','健康状况','毕业院校系及专业','主要学习经历','联系地址','入党/团时间','全日制教育','在职教育','奖惩情况(近三年主要奖惩信息)'] work_map = ['参加工作时间','现任职单位及部门','职务','现任职务','职称','奖惩','工作经历','主要工作经历','职称取得时间','职业资格','应聘部门/岗位'] -other_map = ['奖惩','工作经历','主要工作经历','职称取得时间','职业资格','应聘部门/岗位','是否接受调剂职级/岗位'] +other_map = ['工作经历','主要工作经历','职称取得时间','职业资格','应聘部门/岗位','是否接受调剂职级/岗位'] @@ -297,32 +350,35 @@ def fetch_info(data): map_word = base_map + work_map + other_map print("data is {0}".format(data)) print("map_word is {0}".format(map_word)) - + final_res = {} for key, value in data.items(): translation_table = str.maketrans('', '', ' \t\n\r\f\v') clean_key = key.translate(translation_table) print(f"key is {clean_key} ") if clean_key in map_word: - clean_value = value.translate(translation_table) - final_res.append({clean_key:clean_value}) + # clean_value = value.translate(translation_table) + final_res[clean_key] = value return final_res -if __name__ == "__main__": - # 使用方法 - docx_file = "./1.报名登记表.docx" # 替换为你的文件 - result = quick_extract(docx_file) +def extra_resume(file_path): + result = quick_extract(file_path) print(result) - final_res = [] base_data = result['基本信息'] work_data = result['工作信息'] other_data = result['其他信息'] - final_result = [] data = {} data.update(base_data) data.update(work_data) data.update(other_data) res = fetch_info(data) - print(res) + return res + + +if __name__ == "__main__": + # 使用方法 + docx_file = "../1.报名登记表.docx" # 替换为你的文件 + print(extra_resume(docx_file)) +