脚本如何解析地址信息

wen 实用脚本 25

本文目录导读:

脚本如何解析地址信息

  1. 方案一:使用现成的开源库(推荐,最省力)
  2. 方案二:基于规则的通用脚本(轻量级,无依赖)
  3. 方案三:使用 NLP 模型(适合复杂、不规则文本)
  4. 常见问题与优化技巧
  5. 总结:如何选择?

解析地址信息是一个常见的需求,通常指从一段非结构化文本(如“北京市海淀区中关村大街1号”)中提取出省、市、区、街道、门牌号等结构化字段。

根据不同场景和精度要求,有几种主流的解析方法,以下是详细的脚本方案:

使用现成的开源库(推荐,最省力)

这是最推荐的方式,无需自己处理复杂的规则和机器学习模型。

Python - addrParse / postaddr

这两个库专门用于中国地址解析,基于规则和词典。

# 安装: pip install addrparse
from addrparse import parse_addr
# 或者使用 postaddr
# pip install postaddr
# from postaddr import parse
address = "广东省深圳市南山区科技园南区粤海街道R2-B栋5楼"
result = parse_addr(address)
print(result)
# 输出示例: {'province': '广东省', 'city': '深圳市', 'district': '南山区', 'street': '粤海街道', 'detail': 'R2-B栋5楼'}

Python - 高德/百度地图 API(最准确,但需联网)

适合需要极高准确率(如电商、物流)且允许网络请求的场景。

import requests
# 以高德地图地理编码API为例(需申请Key)
API_KEY = "你的高德Key"
address = "北京市朝阳区望京SOHO T1"
url = f"https://restapi.amap.com/v3/geocode/geo?key={API_KEY}&address={address}"
response = requests.get(url)
data = response.json()
if data['status'] == '1' and data['geocodes']:
    # 解析结构化地址
    addr_component = data['geocodes'][0]
    print(addr_component['province'])  # 北京
    print(addr_component['city'])      # 北京市
    print(addr_component['district'])  # 朝阳区
    print(addr_component['street'])    # 望京街道

基于规则的通用脚本(轻量级,无依赖)

如果你不想调用API也不想下载第三方库,可以用正则表达式加词典实现基础解析。

Python 示例(纯规则+省市区词典)

import re
# 定义省市区简单词典(实际使用时需要更全的列表)
PROVINCES = ["北京", "天津", "上海", "重庆", "河北", "山西", "广东", "深圳", "浙江"...]
CITY_KEYWORDS = ["市"]
DISTRICT_KEYWORDS = ["区", "县", "县级市"]
STREET_KEYWORDS = ["街道", "镇", "乡", "路", "街", "大道"]
def parse_address(address):
    result = {
        "province": "",
        "city": "",
        "district": "",
        "street": "",
        "detail": ""
    }
    # 1. 提取省份(简单匹配)
    for prov in PROVINCES:
        if address.startswith(prov):
            result["province"] = prov
            address = address[len(prov):]
            break
    # 2. 提取城市(匹配第一个出现的“市”)
    city_match = re.search(r"(.*?市)", address)
    if city_match:
        result["city"] = city_match.group(1)
        address = address[city_match.end():]
    # 3. 提取区/县
    district_match = re.search(r"(.*?[区县])", address)
    if district_match:
        result["district"] = district_match.group(1)
        address = address[district_match.end():]
    # 4. 提取街道(匹配第一个出现的街道/镇/路等)
    street_match = re.search(r"(.*?[街道镇路大道])", address)
    if street_match:
        result["street"] = street_match.group(1)
        address = address[street_match.end():]
    # 5. 剩余部分为详细地址
    result["detail"] = address.strip()
    return result
# 测试
addr = "广东省深圳市南山区粤海街道科技园南路1号"
print(parse_address(addr))
# 输出:{'province': '广东', 'city': '深圳市', 'district': '南山区', 'street': '粤海街道', 'detail': '科技园南路1号'}

使用 NLP 模型(适合复杂、不规则文本)

对于用户手写输入、包含错别字或非常规格式的地址,可以使用基于BERT的命名实体识别(NER)模型。

示例:使用 pip 安装 transformers 加载预训练模型

# 安装: pip install transformers torch
from transformers import pipeline
# 加载中文地址解析模型(如清华大学的地址解析模型)
# 注意:可能需要从 HuggingFace 下载特定模型
ner_pipeline = pipeline("ner", model="bert-base-chinese")  # 通用NER
# 更推荐使用专门训练的地址模型(如 "Address-NER")
# 这里以简单示例说明:
address = "上海市浦东新区张江高科技园区郭守敬路498号"
result = ner_pipeline(address)
# 输出结果需要结合规则后处理成省市区格式
print(result)
# 实际生产环境可使用:https://huggingface.co/uer/bert-base-chinese-ner

常见问题与优化技巧

  1. 处理缺失字段:很多地址会省略省份或城市,北京市朝阳区”北京”既是省也是市,建议建立层级映射词典
    • 直辖市映射:北京 -> 省:北京,市:北京
    • 县级市映射:如果提取到“昆山市”,应识别为城市,并映射到江苏省。
  2. 处理前缀:用户可能输入“收货地址:”、“我家在”等前缀,需先用正则过滤:
    address = re.sub(r'^(收货地址|地址|我家在|送至)[:: ]', '', raw_text)
  3. 处理模糊匹配:用户可能写“南京鼓楼区”而非“南京市鼓楼区”,规则需要允许“市”字可省略。
  4. 性能优化:如果处理大量数据(百万级),addrParse 库比调用API快数百倍。

如何选择?

场景 推荐方案 原因
小批量、高精度 高德/百度地图 API 正确率接近100%,自动修正错别字
通用开发、个人项目 addrParse / postaddr 无网络请求,本地快速解析
批量清洗历史数据 基于规则的纯脚本(方案二) 速度快,可定制性强,无外部依赖
用户手工输入、口语化严重 NLP模型(BERT) 对不规则文本(如“张江镇上”)理解能力强

给新手的建议:先试 pip install addrparse,调用一次函数看结果,如果效果满意,就无需折腾其他方案。

抱歉,评论功能暂时关闭!