python:解决从字符串中提取省市区的问题

您所在的位置:网站首页 如何把省市县乡合并在一个表格 python:解决从字符串中提取省市区的问题

python:解决从字符串中提取省市区的问题

2024-01-28 23:00| 来源: 网络整理| 查看: 265

需求

从发货订单的地址中,如下的字符串: "浙江省温州市永嘉县岩头镇芙蓉新村15栋" "温州XX永嘉县岩头镇芙蓉新村15栋" "浙江X永嘉县岩头镇芙蓉新村15栋" "永嘉X岩头镇芙蓉新村15栋" "XXXXX温州市XXXXX永嘉县岩头镇芙蓉新村15栋" 精确提取出省市区

解决思路

1.获取国内最新的省市区县数据并导入数据库 2.将地址分词 3.将所有的关键词,依次同省市县三级数据比较 从而获取出精确的省,市,区县

补丁: 1.若匹配不出省,则匹配全国的市,增大市一级匹配概率 2.若匹配不出市,则匹配全国或全省的区县,增大区县一级匹配概率 3.匹配出县后,再根据县,匹配出所在市所在省的数据 4.去除分词中类似 ['镇', '区', '县', '号'] 这样的单字,降低错误命中 5.若省市县三级均匹配不出,则说明无省市县三级数据

放弃的思路: 1.正则匹配。因为所要分词的数据非常无规律,可能没有省什么的,匹配效果不佳。 2.省市县数据放到json文件中。因为要做类似关键词对比这样的操作,有频繁的数据查询匹配,所以最好将数据存入数据库中去,好提高效率。

执行 1.获取国内最新的省市区县数据并导入数据库

我的数据来源是国家民政部官网: http://www.mca.gov.cn/article/sj/xzqh/2019/ 在这个网站中,能获取到最新的省市县: http://www.mca.gov.cn/article/sj/xzqh/2019/201908/201908271607.html

然后撸下来,插入数据库中。 我的方法是: 1)拷贝网页内容到excel 2)python脚本读取excel文件,并插入数据库

建表语句如下:

CREATE TABLE `T_Province` ( `ProID` varchar(50) NOT NULL, `ProName` varchar(50) DEFAULT NULL, PRIMARY KEY (`ProID`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; CREATE TABLE `T_City` ( `CityID` varchar(50) NOT NULL, `CityName` varchar(50) DEFAULT NULL, `ProID` varchar(50) DEFAULT NULL, PRIMARY KEY (`CityID`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; CREATE TABLE `T_District` ( `DisID` varchar(50) NOT NULL, `DisName` varchar(50) DEFAULT NULL, `CityID` varchar(50) DEFAULT NULL, `ProID` varchar(50) DEFAULT NULL, PRIMARY KEY (`DisID`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

脚本语句我就不再写了,需要注意的是,北京天津上海重庆四个直辖市,没有市一级的数据,我做了补全。 类似:‘北京市,北京市,朝阳区’ 这样方便对地址的匹配,也方便逻辑的连贯性。

2.将地址分词

地址分词,我使用的是jieba这个库来做的 jieba就是“结巴”中文分词 github:https://github.com/fxsjy/jieba

安装说明

代码对 Python 2/3 均兼容 全自动安装:easy_install jieba 或者 pip install jieba / pip3 install jieba 半自动安装:先下载 http://pypi.python.org/pypi/jieba/ ,解压后运行 python setup.py install 手动安装:将 jieba 目录放置于当前目录或者 site-packages 目录 通过 import jieba 来引用

使用方法 #encoding=utf-8 import jieba seg_list = jieba.cut("我来到北京清华大学", cut_all=True) print("Full Mode: " + "/ ".join(seg_list)) # 全模式 seg_list = jieba.cut("我来到北京清华大学", cut_all=False) print("Default Mode: " + "/ ".join(seg_list)) # 默认模式 seg_list = jieba.cut("他来到了网易杭研大厦") print(", ".join(seg_list)) seg_list = jieba.cut_for_search("小明硕士毕业于中国科学院计算所,后在日本京都大学深造") # 搜索引擎模式 print(", ".join(seg_list))

而且github 上有非常详尽的使用方法,请自行查阅。

3.将所有的关键词,依次同省市县三级数据比较

我的python 脚本

# -*- coding: UTF-8 -*- import sql import jieba import json def address_match(address): if not address: return {} address = address.replace(' ', '') # 查省 sql_str = 'select * from tools.T_Province;' province_data = sql.myOperationdb.query(sql_str) seg_list = jieba.lcut(address, cut_all=False) # 对分出的关键词去出对查询结果影响较大的关键词,而且只去单个的分词 for key in seg_list: if key.encode('UTF-8') in ['镇', '区', '县', '号']: seg_list.remove(key) province_dict = {} for item in province_data: for key in seg_list: if key in item['ProName']: province_dict = item break if province_dict: break # 查市 if not province_dict: sql_str = 'select * from tools.T_City;' else: sql_str = 'select * from tools.T_City where ProID = \'' + province_dict['ProID'] + '\';' city_data = sql.myOperationdb.query(sql_str) city_dict = {} if len(city_data) == 1: city_dict = city_data[0] else: for item in city_data: for key in seg_list: if key in item['CityName']: city_dict = item break if city_dict: break # 查区县 if not city_dict: if not province_dict: sql_str = 'select * from tools.T_District' else: sql_str = 'select * from tools.T_District where ProID = \'' + province_dict['ProID'] + '\';' else: sql_str = 'select * from tools.T_District where CityID = \'' + city_dict['CityID'] + '\';' dis_data = sql.myOperationdb.query(sql_str) dis_dict = {} index = 0 if len(dis_data) == 1: dis_dict = dis_data[0] else: for item in dis_data: for key in seg_list: if key in item['DisName']: dis_dict = item index = address.decode('utf8').index(key) break if dis_dict: break if not dis_dict: return {} else: if not province_dict: sql_str = 'select * from tools.T_Province where ProID = \'' + dis_dict['ProID'] + '\';' province_dict = sql.myOperationdb.query(sql_str) province_dict = province_dict[0] if not city_dict: sql_str = 'select * from tools.T_City where CityID = \'' + dis_dict['CityID'] + '\';' city_dict = sql.myOperationdb.query(sql_str) city_dict = city_dict[0] address_dict = { 'province': province_dict['ProName'], 'city': city_dict['CityName'], 'dis': dis_dict['DisName'], 'add': address.decode('utf8')[int(index) + len(key):] } print address return address_dict

其中 sql 模块,是我写的一个sql处理类 代码如下:

# -*- coding: UTF-8 -*- import pymysql import sys from decimal import Decimal reload(sys) class Operationdb(object): def __init__(self): try: self.conn = pymysql.connect(host='localhost', user='root', passwd='root', charset='utf8', use_unicode=True, db='tools', port=3306, cursorclass=pymysql.cursors.DictCursor) self.cur = self.conn.cursor() except pymysql.Error as e: print ("创建数据库连接失败|Mysql Error %d: %s" % (e.args[0], e.args[1])) def __del__(self): self.cur.close() self.conn.close() def query(self, sql): self.cur.execute(sql) data = self.cur.fetchall() if data: return data else: return 0 def execute(self, sql): try: self.cur.execute(sql) self.conn.commit() return True except pymysql.Error as e: self.conn.rollback() return False def executemany(self, sql, d_list): try: self.cur.executemany(sql, d_list) self.conn.commit() except pymysql.Error as e: self.conn.rollback() myOperationdb = Operationdb()

最终执行效果:

浙江省温州市永嘉县岩头镇芙蓉新村15栋 {"province": "浙江省", "city": "温州市", "add": "岩头镇芙蓉新村15栋", "dis": "永嘉县"} 温州XX永嘉县岩头镇芙蓉新村15栋 {"province": "浙江省", "city": "温州市", "add": "岩头镇芙蓉新村15栋", "dis": "永嘉县"} 浙江X永嘉县岩头镇芙蓉新村15栋 {"province": "浙江省", "city": "温州市", "add": "岩头镇芙蓉新村15栋", "dis": "永嘉县"} 永嘉X岩头镇芙蓉新村15栋 {"province": "浙江省", "city": "温州市", "add": "X岩头镇芙蓉新村15栋", "dis": "永嘉县"} XXXXX温州市XXXXX永嘉县岩头镇芙蓉新村15栋 {"province": "浙江省", "city": "温州市", "add": "岩头镇芙蓉新村15栋", "dis": "永嘉县"}


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3