python, json, xml的转换

今天在做数据处理时用到了百度地图API,结合Geopy来做地点的定位,当然需要坐标啦。

可惜的是,作为新手我没注意到百度返回的是xml,需要转换成json,然后在转换成Python里的字典(dict),方便嵌套引用。百度返回的是个这样的字符串,但是打开url返回的没有第一行header。开始我以为是header问题,还把第一行去掉了,其实是多此一举。

<?xml version="1.0" encoding="utf-8" ?> 
<GeocoderSearchResponse> 
	<status>OK</status>
	<result>
					<location>
				<lat>37.195699</lat>
				<lng>122.096751</lng>
			</location>	
			<precise>0</precise>
			<confidence>30</confidence>
			<level>道路</level>
			</result>	
</GeocoderSearchResponse>
<GeocoderSearchResponse> 
	<status>OK</status>
	<result>
					<location>
				<lat>37.195699</lat>
				<lng>122.096751</lng>
			</location>	
			<precise>0</precise>
			<confidence>30</confidence>
			<level>道路</level>
			</result>	
</GeocoderSearchResponse>

这个xml可以尝试在 https://www.json.cn/# 进行转换(转换成json的dict格式),如果成功说明数据没问题。在python里可以用xmltodict这个第三方包来把xml转换成json(到了这里离我们所需要的Pythondict就是咫尺之遥了):

{
 "GeocoderSearchResponse": {
  "status": "OK",
  "result": {
   "location": {
    "lat": "37.195699",
    "lng": "122.096751"
   },
   "precise": "0",
   "confidence": "30",
   "level": "\u9053\u8def"
  }
 }
}

最后,需要把上面的json用json.loads转换成python里的dict:

{'GeocoderSearchResponse': {'status': 'OK', 'result': {'location': {'lat': '37.195699', 'lng': '122.096751'}, 'precise': '0', 'confidence': '30', 'level': '道路'}}}

到了这里你就能方便地索引了,比如索引这里的lat(dict就是层层嵌套):

print(json_dict['GeocoderSearchResponse']['result']['location']['lat'])

项目完成后再把源码放到github上,参考:

https://blog.csdn.net/qq_39247153/article/details/81984524

https://www.cnblogs.com/chenfulin5/p/7834466.html

(json的用法)

https://blog.csdn.net/JOJOY_tester/article/details/71435935 (介绍xml2dict)

跑代码的时候又发现数据的另外一个问题,个别医院的地址栏竟然有两个地址,分号分开的!程序就崩溃了。如下:

mysql> SELECT * FROM top_tier3_hospital WHERE address LIKE "%北京市东城区天坛西里4号%";
+------------------------------+---------------+-----------+--------+---------------------------------------------------------------------+----------------------------------------+
| hospital_name_new            | hospital_tier | Provinces | Cities | address                                                             | phone                                  |
+------------------------------+---------------+-----------+--------+---------------------------------------------------------------------+----------------------------------------+
| 首都医科大学附属北京口腔医院 | 三级甲等      | 北京市    | 东城区 | 北京市东城区天坛西里4号(天坛);北京市东城区锡拉胡同11号(王府井) | 010-67099114(总机);67099284(咨询) |
+------------------------------+---------------+-----------+--------+---------------------------------------------------------------------+----------------------------------------+
1 row in set (0.00 sec)

SQL查重和防止数据重复

今天从爬下来的医院数据创建一个新数据表时遇到了错误,这个也是预料中的,因为爬取的医院名称有的在括号内还有一个名称,我处理数据时把括号及里面的数据删除掉了,所以结果肯定有少量重复。解决办法是重新处理数据写入SQL,重新设置primary key

mysql> CREATE TABLE tier3_hospital (UNIQUE (hospital_name_new)) SELECT hospital_name_new,hospital_tier,Provinces,Cities,address,phone FROM hospital_list_table WHERE hospital_tier LIKE “%三 级%”;
ERROR 1062 (23000): Duplicate entry ‘吉林大学第三医院’ for key ‘hospital_name_new’
mysql> SELECT COUNT(*) as repetitions, hospital_name_new
-> FROM hospital_list_table
-> GROUP BY hospital_name_new
-> HAVING repetitions > 1;
+————-+———————————-+
| repetitions | hospital_name_new |
+————-+———————————-+
| 2 | 中德精神康复医院 |
| 2 | 兴义市人民医院 |
| 2 | 内蒙古胸科医院 |
| 2 | 南京市长江医院第四医院 |
| 2 | 南京长江医院第三医院 |
| 2 | 南京长江医院第二医院 |
| 2 | 吉林华侨医院 |
| 2 | 吉林大学第三医学院分院 |
| 2 | 吉林大学第三医院 |
| 2 | 呼伦贝尔盟第二人民医院 |
| 3 | 唐山华新纺织集团医院 |
| 2 | 四川省中医药研究院中医医院 |
| 2 | 太原市小店区亲贤医院 |
| 2 | 太原市煤炭气化公司职工医院 |
| 2 | 孝感市人民医院 |
| 2 | 安丘市白求恩医院 |
| 2 | 安丘市精神卫生中心 |
| 2 | 安溪县中医院 |
| 2 | 宜宾市康复医院 |
| 2 | 广州市番禺区岐山医院 |
| 2 | 广西亭凉医院 |
| 2 | 广西龙泉山医院 |
| 2 | 张家口市肺科医院 |
| 2 | 本溪钢铁公司胸科医院 |
| 2 | 梧州市里湖医院 |
| 2 | 武汉钢铁公司第二职工医院 |
| 2 | 武汉钢铁公司第二职工医院结核病院 |
| 2 | 河北省中医院 |
| 2 | 淮南朝阳医院 |
| 2 | 牡丹江市结核医院 |
| 2 | 苏州九龙医院 |
| 2 | 襄阳汽车轴承股份有限公司医院 |
| 2 | 镇江市烧伤医院 |
| 2 | 长治市商业医院 |
+————-+———————————-+
34 rows in set (0.04 sec)

下面这个情况就很尴尬了:

mysql> SELECT * FROM hospital_list_table
-> WHERE hospital_name_new=’吉林大学第三医院’;
+———————————————-+——————-+————————-+———–+——————+—————+——————————-+————–+——-+———+
| hospital_name | hospital_name_new | city | Provinces | Cities | hospital_tier | address | phone | email | website |
+———————————————-+——————-+————————-+———–+——————+—————+——————————-+————–+——-+———+
| 吉林大学第三医院 | 吉林大学第三医院 | 吉林省-延边朝鲜族自治州 | 吉林省 | 延边朝鲜族自治州 | 三级甲等 | 吉林省长春市二道区仙台大街2号 | 0431-4646331 | NULL | NULL |
| 吉林大学第三医院(中日联谊二部)(吉大三院) | 吉林大学第三医院 | 吉林省-长春市 | 吉林省 | 长春市 | 三级甲等 | 吉林省长春市仙台大街2号 | 0431-5656921 | NULL | NULL |
+———————————————-+——————-+————————-+———–+——————+—————+——————————-+————–+——-+———+
2 rows in set (0.02 sec)

http://huanyouchen.github.io/2018/05/22/mysql-error-1406-Data-too-long-for-column/

另外,mysql报错:1406, “Data too long for column”,可以:

在MySQL中设置这个:

mysql> SET @@global.sql_mode= ”;