发现问题背景:
由于前几天参加了一个数据分析比赛,要对其中13多万的数据中的城市进行分布可视化,进而分析,所以要爬取各个城市的经纬度,就采用了百度地图的API来爬取。
先上代码:
import json
from urllib.request import urlopen, quote
import requests,csv
def getlnglat(address):
url = ‘http://api.map.baidu.com/geocoding/v3/’
output = ‘json’
ak = ‘FdOCynWnqWD3BylVaYceQY2ZHAMr0byb’
add = quote(address) #为防止乱码,先用quote进行编码
uri = url + '?' + 'address=' + add + '&output=' + output + '&ak=' + ak
req = urlopen(uri)
res = req.read().decode() #将其他编码的字符串解码成unicode
temp = json.loads(res) #对json数据进行解析
return temp
f = open(‘city.csv’,‘w’,encoding=‘utf-8’,newline=’’)
csv_writer = csv.writer(f)
csv_writer.writerow([“city”, “lng”, “lat”])
for i in address:#address为比赛数据集中的城市
lng = getlnglat(i)[‘result’][‘location’][‘lng’] #获取经度
lat = getlnglat(i)[‘result’][‘location’][‘lat’] #获取纬度
str_temp = [i,lng,lat]
csv_writer.writerow(str_temp) #写入文档
f.close()
然后出现了一个错误:
KeyError Traceback (most recent call last)
in
18 csv_writer.writerow([“city”, “lng”, “lat”])
19 for i in address:
—> 20 lng = getlnglat(i)[‘result’][‘location’][‘lng’] #采用构造的函数来获取经度
21 lat = getlnglat(i)[‘result’][‘location’][‘lat’] #获取纬度
22 str_temp = [i,lng,lat]
KeyError: ‘result’
在确保你的ak无误以及url格式正确的情况下,还出现这个问题,有可能是对面找不到你所爬取的城市的相关信息,所以我看了一下我已经写入的城市的数据,将其与原来的城市数据进行对比发现,石家庄这个城市的信息爬取不到!在网上找不到相关的解决信息,就差打电话问百度地图的相关工作人员了。但我在翻看百度地图API贴吧网友的帖子时突然受到启发,address参数是必填的:
翻开请求参数的含义我发现,address可以是城市名也可以是地点名,如果只单单给一个城市名的话(不加市,例如“朔州”)它就有可能不能解析出这到底是城市名还是地点名,因为同名的有很多,光光故宫就有4个,所以要再精确一点,所以我尝试了在城市名后加个“市”字,发现有些城市还是爬取不到,所以要再加入限制条件:添加city参数
所以我将代码改成如下:
import json
from urllib.request import urlopen, quote
import requests,csv
def getlnglat(address):
url = ‘http://api.map.baidu.com/geocoding/v3/’
output = ‘json’
ak = ‘FdOCynWnqWD3BylVaYceQY2ZHAMr0byb’ #
add = quote(address) #为防止乱码,先用quote进行编码
city=quote(address)
uri = url + ‘?’ + ‘address=’ + add + ‘&output=’ + output + ‘&ak=’ + ak+’&city=’+city
req = urlopen(uri)
res = req.read().decode() #将其他编码的字符串解码成unicode
temp = json.loads(res) #对json数据进行解析
return temp
f = open(‘city.csv’,‘w’,encoding=‘utf-8’,newline=’’)
csv_writer = csv.writer(f)
csv_writer.writerow([“city”, “lng”, “lat”])
for i in address:
lng = getlnglat(i)[‘result’][‘location’][‘lng’] #获取经度
lat = getlnglat(i)[‘result’][‘location’][‘lat’] #获取纬度
str_temp = [i,lng,lat]
csv_writer.writerow(str_temp) #写入文档
f.close()
添加限制参数city后,顺利爬取成功!
另外还有一个可能出现这个Error的问题,就是当你百度的日限额用完时,也会出现这个bug。