#!/usr/bin/env python#-*- coding: utf-8 -*-#@File : paqu_area.py#@Author: 田智凯#@Date : 2020/3/12#@Desc :根据完成单位名称(取第一个)爬取得到省市县以及行政代码
importurllib.request, urllib.parse, urllib.errorimportjsonimporthashlibimportpymssqlimporttimefrom multiprocessing importPoolfrom paqu.area importArea
MyAK= '###'MySK= '###'lat=0#记录纬度
lng=0#记录经度
str_area=0#记录具体地理信息
adcode=0#记录行政代码
err=0#记录JSON获取失败数
#百度API地理服务接口;处理得到url
defget_url(name):#GET请求 http://api.map.baidu.com/geocoding/v3/?address=北京市海淀区上地十街10号&output=json&ak=您的ak&callback=showLocation
queryStr = '/geocoding/v3/?address={}&output=json&ak={}'.format(name,MyAK)#对queryStr进行转码,safe内的保留字符不转换
encodedStr = urllib.parse.quote(queryStr, safe="/:=&?#+!$,;'@()*[]")#在最后追加sk
rawStr = encodedStr +MySK#计算sn
sn = (hashlib.md5(urllib.parse.quote_plus(rawStr).encode("utf8")).hexdigest())#由于URL里面含有中文,所以需要用parse.quote进行处理,然后返回最终可调用的url
url = urllib.parse.quote("http://api.map.baidu.com" + queryStr + "&sn=" + sn, safe="/:=&?#+!$,;'@()*[]")#print('URL:', url)
returnurl#根据url得到json数据
defget_json(url):globalerr#从API读取数据
req =urllib.request.urlopen(url)
res=req.read().decode()#解析数据
try:#将 JSON 对象转换为 Python 字典
json_data =json.loads(res)except:
json_data=Noneif not json_data or 'status' not in json_data or json_data['status'] !=0:
err=err+1
'''else:
#输出Json数据
print(json.dumps(json_data, indent=4, ensure_ascii=False))'''
returnjson_data#百度API地理服务接口;获取经纬度坐标
defget_lnglat(json_data):#Python中定义函数时,若想在函数内部对函数外的变量进行操作,就需要在函数内部声明其为global
globallat,lng
lat= json_data["result"]["location"]["lat"]
lng= json_data["result"]["location"]["lng"]#print('纬度', lat, '经度', lng)
#百度API逆地理服务接口;处理得到url
defget_url2(lat,lng):#GET请求 http://api.map.baidu.com/reverse_geocoding/v3/?ak=您的ak&output=json&coordtype=wgs84ll&location=31.225696563611,121.49884033194
queryStr = '/reverse_geocoding/v3/?ak={}&output=json&coordtype=wgs84ll&location={},{}'.format(MyAK,str(lat),str(lng))#对queryStr进行转码,safe内的保留字符不转换
encodedStr = urllib.parse.quote(queryStr, safe="/:=&?#+!$,;'@()*[]")#在最后追加sk
rawStr = encodedStr +MySK#计算sn
sn = (hashlib.md5(urllib.parse.quote_plus(rawStr).encode("utf8")).hexdigest())#由于URL里面含有中文,所以需要用parse.quote进行处理,然后返回最终可调用的url
url = urllib.parse.quote("http://api.map.baidu.com" + queryStr + "&sn=" + sn, safe="/:=&?#+!$,;'@()*[]")#print('URL:', url)
returnurl#百度API地理服务接口;解析Json数据;获取行政代码等具体信息
defget_info(json_data):globalstr_area,adcode
province=json_data["result"]["addressComponent"]["province"]
city=json_data["result"]["addressComponent"]["city"]
district=json_data["result"]["addressComponent"]["district"]
adcode=json_data["result"]["addressComponent"]["adcode"]
str_area=province+city+district#print("地理:",str_area)
#print("行政代码:",adcode)
#汇总
defget_area_main(danwei):#得到经纬度
url=get_url(danwei)
json_data=get_json(url)
get_lnglat(json_data)#获取详细信息
url2=get_url2(lat, lng)
json_data=get_json(url2)
get_info(json_data)#查询数据库,返回list
defget_dbdata():
conn= pymssql.connect("127.0.0.1", "sa", "tzk19991029", "test", charset="GBK")
cursor=conn.cursor()
list=[]try:
cursor.execute('SELECT id,wc_danwei FROM kettle2')for row incursor:
area=Area()
id=row[0]
danwei=row[1].split()[0]try:
get_area_main(danwei)except:#有的地点百度地图上没有,这时选择跳过去
continuearea.set_id(id)
area.set_danwei(danwei)
area.set_area(str_area)
area.set_adcode(adcode)
list.append(area)
cursor.close()except:#发生错误时回滚
conn.rollback()returnlist#修改数据库表
defupdate_dbdata(area):
conn= pymssql.connect("127.0.0.1", "sa", "tzk19991029", "test", charset="utf8")
cursor=conn.cursor()
sql="UPDATE kettle2 SET area='{}',adcode='{}' WHERE id='{}'".format(area.get_area(),area.get_adcode(),area.get_id())#print(sql)
try:
cursor.execute(sql)#提交到数据库执行
conn.commit()
cursor.close()except:#发生错误时回滚
conn.rollback()if __name__ == '__main__':
start=time.time()
list=get_dbdata()print(len(list))#多进程
pool = Pool(processes=4) #创建进程池
pool.map(update_dbdata, list)
pool.close()
end=time.time()print('json数据获取失败数', err)print("程序用时",end-start)