python中有cpca库, 可以匹配省市区并返回. 但这个库有些老, 好多年不更新, 像深圳龙华区这些近几年升级为区的都没有. 所以需要结合正则实现.
python还有另外一个geopy库也可以实现, 但是这个库需要实时通过API读取, 还总是timeout, 所以放弃这个方案.
UiBot本来支持python扩展来解决, 但是不知为何Uibot自带的python对cpca支持有问题, 始终报错, 所以放弃, 改为Uibot调用系统命令读取打印输出的方式曲线救国.
python代码都是GPT4 Turbo写的, 自己做了小修改.
Uibot测试:

PyTools('parse_address', '广东省深圳市龙华区深圳北站')

Uibot函数:

// 由于通过uibot的python调用存在问题(import cpca始终报错), 所以通过命令行调用
// python路径直接写在tools.bat中, 使用系统where python给出的路径, 避免uibot调用错误的python版本. 此时在系统中使用Pip安装的库可以直接在这儿使用
// tools.bat直接调用执行tools.py. 具体函数在tools.py中实现
// 以Json字符串形式返回
Function PyTools(func, params)
    // params支持单字符串的单参数或者数组形式的多参数
    Dim Ret
    If type('params') = 'string'
        Ret = Sys.Command(@res"tools.bat "+func+" "+params)
    else
        Dim cmd = @res"tools.bat "+func
        For Each p In params 
            cmd = cmd + " " + p
        Next
        Ret = Sys.Command(@res"tools.bat "+func+cmd)
    End if 
    return JSON.Parse(Ret)
End Function

系统命令 tools.bat和python脚本tools.py, 放在uibot项目的res目录下. 如果不放心调用哪个版本的python,可以积极在python前面加路径.

@echo off
python.exe D:\folder\to\project\res\tools.py %1 %2 %3 %4 %5 %6 %7 %8 %9
@echo on

tool.py部分. 大多数是gpt4写的

# tools.py

import sys,re,json
import cpca

def parse_address(address):
    a = ""
    a1 = parse_address1(address)
    a2 = parse_address2(address)
    # 策略: 长度相同优选a1方法, 否则选a2
    if len(a2) <= len(a1):
        a = a1
    else:
        a = a2
    # return f"{a[0]}|{a[1]}|{a[2]}"
    return json.dumps(a, ensure_ascii=False)

# 采用cpca获取省市区. 好处: 不写省市区这几个字都能识别. 问题: 可能有数据库过期问题(龙华区无法识别)
def parse_address1(address):
    # 使用 cpca 库解析地址并返回 DataFrame
    df = cpca.transform([address])
    location = df.iloc[0]  # 提取第一行数据,即我们需要的地址解析结果

    # 返回省市区字符串,用 "|" 分隔
    # return f"{location['省']}|{location['市']}|{location['区']}"
    return list(filter(None,[location['省'], location['市'], location['区']]))

# 采用正则表达式获取省市区. 好处: 不需要更新数据库. 问题: 必须有省市区这几个字.
def parse_address2(address):
    # 更新省/直辖市的匹配模式以处理没有“市”字的直辖市情况
    pattern = re.compile(
        r'(?P<province>[^省]+省|[^自治区]+自治区|北京|天津|上海|重庆)?'
        r'(?P<city>[^市]+市|[^自治州]+自治州|[^地区]+地区|[^盟]+盟)?'
        r'(?P<district>[^县]+县|[^区]+区|[^旗]+旗|[^自治县]+自治县|[^林区]+林区|[^特别行政区]+特别行政区)?'
    )
    match = pattern.search(address)
    if not match:
        return "无法提取地址信息"

    province, city, district = match.group('province', 'city', 'district')

    # 北京、天津、上海和重庆作为直辖市,如果匹配到省份但没有匹配到市,将省份的名字赋给城市
    if province in ['北京', '天津', '上海', '重庆'] and not city:
        city = province
        city = city + '市'

    # 如果没有匹配到,则用空字符串代替
    province = province if province else ''
    city = city if city else ''
    district = district if district else ''

    # 以"|"连接非空字符串
    # result = '|'.join(filter(None, [province, city, district]))

    return list(filter(None,[province, city, district]))

def test_parse_address():
    print(parse_address('广东省深圳市龙华区深圳北站'))


if __name__ == "__main__":
    if len(sys.argv) < 3:
        print("Usage: python tools.py parse_address 'Your Address String Here'")
        sys.exit(1)
    if sys.argv[1] == "parse_address":
        input_address = sys.argv[2]
        result = parse_address(input_address)
        print(result)
    elif sys.argv[1] == "test_parse_address":
        test_parse_address()
    else:
        print('["没有正确的函数名"]')

标签: none 阅读量: 742

添加新评论