Python实现OCR地址提取后国家州识别及完整地址输出方案咨询
地址解析实现方案
全球州级行政区数据管理方案
不用依赖在线第三方服务,本地维护结构化映射表是最可控、长期成本最低的方案:
- 数据结构和你已有的国家字典对齐,统一存为JSON格式即可,核心结构为「标准国家名:对应国家所有一级行政区(州/省/邦)信息」,每个行政区条目下要收录标准名、常用缩写、日常别名、常见拼写错误、多语言译名——比如你示例里OCR识别出的
Harayana就是印度哈里亚纳邦Haryana的常见书写误差,这类变体一定要提前收录,不然会出现匹配失败的问题。 - 不用一开始就凑齐全球所有国家的行政区数据,按你业务实际遇到的地址所属国家优先级逐步补充就行,先覆盖高频国家,再补冷门地区,初期维护量非常小。
- 数据结构参考示例:
{ "India": { "country_aliases": ["IND", "印度"], "subdivisions": { "Haryana": ["Harayana", "哈里亚纳邦", "HR"], "Maharashtra": ["马哈拉施特拉邦", "MH"] } } }
OCR文本后的解析逻辑实现
整个流程不用依赖复杂的NLP模型,本地就能跑通,步骤如下:
- 第一步做OCR文本清洗:把提取到的文本按行拆分,过滤无关内容:跳过带
Tel:/电话标识的联系方式行、纯数字的邮编/电话行、明显是人名/地标指引的描述行(比如示例里的Near Mother Dairy这类),剩下的内容作为地址候选行,统一做转小写、去多余空格的标准化处理。 - 第二步匹配国家:遍历你已有的国家名称字典,和候选地址行做模糊匹配(用编辑距离算法即可,相似度阈值设为0.8,足够覆盖小的拼写错误),命中后锁定对应国家。
- 第三步匹配州级行政区:根据上一步匹配到的国家,调取该国家对应的所有一级行政区(含别名/拼写变体)列表,在候选地址行里做包含匹配+模糊匹配,命中后提取对应的标准行政区名。
- 最后把清洗后的完整地址、匹配到的国家、匹配到的州级行政区统一输出即可。
核心逻辑参考代码:
from Levenshtein import ratio import json # 加载本地维护的国家字典、行政区数据 with open("country_dict.json", "r", encoding="utf-8") as f: country_dict = json.load(f) with open("subdivision_data.json", "r", encoding="utf-8") as f: subdivision_data = json.load(f) def parse_address(ocr_raw_text): # 拆分文本行,过滤空行 raw_lines = [line.strip() for line in ocr_raw_text.split("\n") if line.strip()] candidate_addr_lines = [] # 过滤非地址行 for line in raw_lines: if line.lower().startswith("tel"): continue if line.replace(" ", "").isdigit(): continue candidate_addr_lines.append(line) full_address = ", ".join(candidate_addr_lines) # 匹配国家 matched_country = None for line in candidate_addr_lines: line_processed = line.lower() for std_country, info in country_dict.items(): all_country_names = info.get("aliases", []) + [std_country] for name in all_country_names: if ratio(line_processed, name.lower()) >= 0.8: matched_country = std_country break if matched_country: break if matched_country: break # 匹配一级行政区 matched_subdivision = None if matched_country and matched_country in subdivision_data: sub_info = subdivision_data[matched_country]["subdivisions"] for line in candidate_addr_lines: line_processed = line.lower() for std_sub, aliases in sub_info.items(): all_sub_names = aliases + [std_sub] for name in all_sub_names: name_low = name.lower() # 地址行通常是城市+州+邮编的组合,同时支持包含匹配和模糊匹配 if name_low in line_processed or ratio(line_processed, name_low) >= 0.8: matched_subdivision = std_sub break if matched_subdivision: break if matched_subdivision: break return { "full_address": full_address, "country": matched_country, "subdivision": matched_subdivision } # 测试提供的示例OCR结果 if __name__ == "__main__": test_ocr_text = """Subash Mittal Near Mother Dairy Close to Radha Krishna Mandir Gurgaon Harayana 122001 India Tel : 9999999999""" print(parse_address(test_ocr_text))
优化提示
- 模糊匹配用轻量的编辑距离库足够,不需要调用大模型或外部接口,响应速度快,也没有调用限制和额外成本。
- 可以加个置信度判断,如果国家或者行政区的匹配相似度低于0.7,就把这条地址标记为待人工校验,避免误匹配。
- 初期不用急于补全全球数据,先把当前业务高频遇到的国家行政区数据录进去,后续每遇到匹配失败的案例,把对应的行政区别名补到字典里就行,数据积累越多匹配准确率越高。
内容的提问来源于stack exchange,提问作者Tanuj Kanda
相关产品推荐
相关产品推荐

