用Python 查看哪个城市中国冬天最热的城市

10被浏览2,772分享邀请回答该回答已被折叠 折叠原因:算法识别自动折叠01 条评论分享收藏感谢收起项目中需要用省市区来进行检索,原想高德地图肯定会有API来获得这些数据,结果没有找到,有一个接口好像可以用,但是会附带大量的边界坐标点。
所以就不如自己把高德的省市区列表扒下来,自己写接口来完成这个功能。
看到高德地图的js的demo里面有这样的展示页面:http://lbs.amap.com/api/javascript-api/example/u/2001-2/,所以我就直接利用它来分析。
省的列表是直接写死在这个界面里的,所以我也照搬,把省都直接写死:
provinceList = ['北京市', '天津市', '河北省', '山西省', '内蒙古自治区', '辽宁省', '吉林省','黑龙江省', '上海市', '江苏省', '浙江省', '安徽省', '福建省', '江西省', '山东省','河南省', '湖北省', '湖南省', '广东省', '广西壮族自治区', '海南省', '重庆市','四川省', '贵州省', '云南省', '西藏自治区', '陕西省', '甘肃省', '青海省', '宁夏回族自治区', '新疆维吾尔自治区', '台灣', '香港特别行&政区', '澳门特别行政区'];
从市列表开始,就要扒高德地图的接口了,首先模仿浏览器的访问设置几个Http头:
send_headers = {
'Accept':'*/*',
'Accept-Encoding':'gzip, deflate, sdch',
'Accept-Language':'zh-CN,q=0.8',
'Connection':'keep-alive',
'Host':'restapi.amap.com',
'Referer':'http://lbs.amap.com/fn/iframe/?id=3556',
然后是根据省名获取市列表的函数:
def getCity(province):
print "Province-&" + province
url = "http://restapi.amap.com/v3/config/district?subdistrict=1&extensions=all&level=province&key=608dc550daf&s=rsv3&output=json&callback=jsonp_" + getJsonP() + "_&keywords=" +
data = getData(url)
item = data['districts'][0];
if item['citycode'] == []:
item['citycode'] = ''
save([item['citycode'], item['adcode'], item['name'], item['center'], item['level'], ''])
for item in data['districts'][0]['districts']:
save([item['citycode'], item['adcode'], item['name'], item['center'], item['level'], ''])
getDistrict(item)
except Exception, e:
print 'retry:' + item['name'] + "-&" + str(e)
这里有跨域访问用的getJsonP、发起网络请求的getData、存数据库的save,这三个函数的具体实现一会再说,先看其它逻辑,高德服务端返回数据是长得这个样子的:
districts域就是搜索的结果,因为这是按名称进行搜索,而不是id,所以很可能会搜出来多个结果,当然省名不会重,但一样得到的是一个JSONArray,所以用data['districts'][0]来得到省的信息,除了直辖市之外,省级单位的citycode都是空的,用item['citycode'] = ''给它一个空字符串做默认值,然后调用save方法把它存入数据库,在上图中也看到了,data['districts'][0]里面还有一个districts域,这里面就是所有市的信息,同样把它们存入数据库,然后针对每个市,去获取区的列表,这里有可能会出现网络问题,所以加上了失败重试。
下面依次来看上面几个关键方法的实现:
1)getJsonP:
跨域访问是通过jsonp回调的方式进行的,函数名都是jsonp_xxxxx_()的形式,这个xxxxx是一个变化的随机数字,我采用依次递增的形式来生成这个jsonp的数字:
jsonp = 9999
def getJsonP():
global jsonp
jsonp = jsonp + 1
if (jsonp & 99999):
jsonp = 10000
return str(jsonp)
这里我保证这个数字是一个5位数(理论上几位都可以),因为在图里可以看到,返回值是jsonp_xxxxx_({aaa})的形式,我们要分析json串需要把前后没用的字符去掉,如果长度固定就很好删了。
2)getData:
发起网络请求并把返回的数据转成JSONObject:
def getDataWithEx(url):
req = urllib2.Request(url,headers=send_headers)
r = urllib2.urlopen(req,timeout=30)
if r.info().get('Content-Encoding') == 'gzip':
buf = StringIO(r.read())
f = gzip.GzipFile(fileobj=buf)
data = f.read()
data = r.read()
return json.loads(data[13:-1])
def getData(url):
response = getDataWithEx(url)
except Exception, e:
print 'retry:' + url + " with error " + str(e)
return response
这里也加入了失败重试,一般的数据都要用gzip进行解码,但是我忘了是哪个了,好像是有一个区的数据很特别没有用gzip,所以这里要分开判断,getJsonP里面介绍了,返回的数据前后是写无用的字符,用data[13:-1]删掉。
这是往MySQL里存数据的函数,没有特殊的点需要介绍,直接上代码:
def save(value):
conn=MySQLdb.connect(host='www.xxx.com',user='xxx',passwd='xxx',port=3306,charset="utf8")
conn.select_db('test')
cur=conn.cursor()
cur.execute("insert into amap(citycode, adcode, name, center, level, areacode) values(%s,%s,%s,%s,%s,%s)",value)
conn.commit()
cur.close()
conn.close()
except MySQLdb.Error,e:
print "Mysql Error %d: %s" % (e.args[0], e.args[1])
跟获取城市列表相似:
def getDistrict(city):
print "-&City-&" + city['name']
url = "http://restapi.amap.com/v3/config/district?subdistrict=1&extensions=all&level=city&key=608dc550daf&s=rsv3&output=json&callback=jsonp_" + getJsonP() + "_&keywords=" + city['name']
data = getData(url)
for possible in data['districts']:
if possible['adcode'] == city['adcode']:
for item in possible['districts']:
save([item['citycode'], item['adcode'], item['name'], item['center'], item['level'], ''])
getBusiness(item)
except Exception, e:
print 'retry:' + item['name'] + "-&" + str(e)
和获取市列表稍微不同的是这里不能直接data['districts'][0]了,按市、区搜就有可能重名了,所以用城市的adcode来匹配,针对匹配上的市,遍历区的信息存入数据库,然后再针对区搜索商圈。
4. 商圈列表
跟获取市列表和获取区列表没有太大的区别:
def getBusiness(district):
print "-&-&District-&" + district['name']
url = "http://restapi.amap.com/v3/config/district?subdistrict=1&extensions=all&level=district&key=608dc550daf&s=rsv3&output=json&callback=jsonp_" + getJsonP() + "_&keywords=" + district['name']
data = getData(url)
for possible in data['districts']:
if possible['adcode'] == district['adcode']:
for item in possible['districts']:
values.append((item['citycode'], item['adcode'], item['name'], item['center'], item['level'], item['areacode']))
saveAll(values)
唯一不同的是直接用saveAll一次性存储所有的数据而不是一条条的save:
def saveAll(values):
conn=MySQLdb.connect(host='www.xxx.com',user='xxx',passwd='xxx',port=3306,charset="utf8")
conn.select_db('test')
cur=conn.cursor()
cur.executemany("insert into amap(citycode, adcode, name, center, level, areacode) values(%s,%s,%s,%s,%s,%s)",values)
conn.commit()
cur.close()
conn.close()
except MySQLdb.Error,e:
print "Mysql Error %d: %s" % (e.args[0], e.args[1])
关键的逻辑就都介绍完了,下面是头部库的导入和编码设置:
# -*- coding: utf-8 -*-
#encoding=utf-8
import urllib2
import sys, json
from StringIO import StringIO
import gzip
import MySQLdb
import datetime
reload(sys)
sys.setdefaultencoding('utf-8')
这里要说的一点是:不知道为什么编译器会报错说setdefaultencoding方法不存在,有这个错误的话不用理会,可以正常运行,如果不设置那么在数据库插入的时候会报下面的一个错误:
UnicodeEncodeError:'latin-1' codec can't encode character
最后是上述方法的调用:
starttime = datetime.datetime.now()
for province in provinceList:
getCity(province)
print 'over'
endtime = datetime.datetime.now()
print (endtime - starttime).seconds
扒数据的时间很长,n多小时,我忘了具体是多久了,而且为了避免出错我是把所有省分成了好几段分别扒的。
如果不想自己扒数据,想直接得到省市区的数据,可以直接我转存的sql文件。
也可以临时使用我的接口(都已失效):
获取省列表:http://www.yxbilu.com/sites/tools/amap/province;
获取市列表:http://www.yxbilu.com/sites/tools/amap/city?adcode=110000(省的adcode);
获取区列表:http://www.yxbilu.com/sites/tools/amap/district?adcode=110100(市的adcode)。
阅读(...) 评论()2017python入门到实战数据分析之城市热视频教程网盘下载2017python入门到实战数据分析之城市热视频教程网盘下载看穿科技族百家号适用人群1、对Python感兴趣的。2、对爬虫感兴趣的。课程概述用Python分析“中国天气网”。来看看中国哪个城市最热。课程目录课时1中国天气网分析10:34课时2获取中国天气网数据16:14课时3获取页面中的省份40:44课时4获取页面中的城市10:35课时5获取城市的最低气温03:45课时6获取所有城市的最低气温06:38课时7最低气温数据可视化下载地址百度搜索:怪兽IT学院本文仅代表作者观点,不代表百度立场。系作者授权百家号发表,未经许可不得转载。看穿科技族百家号最近更新:简介:你知道世界上最疯狂的事作者最新文章相关文章Python爬虫看看哪个城市最热_百度知道
Python爬虫看看哪个城市最热
我有更好的答案
可以关注本公众号,会有一套详细的视频教程免费教大家查找)。我们可以看到,那就是requests库。requests库是一个专门用来从网站上拉取数据的库。这个库的使用,后面我们会讲到,如果您还没有安装这个库,那么可以通过以下命令进行安装;, class_=&#39。因此,要使用beautifulsoup库,要通过以下命令来安装;div&#39、港澳台:在做爬虫之前。我们这里就跟大家分析一下中国天气网的网站:在以上这个中国天气网的页面中。我们可以看到,这也是所有做爬虫需要注意的地方,然后再在每个区域的链接下把这个区域下的所有的城市天气信息爬出来就可以了,首先对爬虫的解题路径做个简单概述。一个爬虫工作分为两步骤:第一步:把你需要爬取的那个网页的数据全部拉下来。第二步是把从网站上拉下来的数据进行过滤,把你需要的提取出来,把不需要的给过滤掉。这就是爬虫的工作原理。准备工作。因此我们要做的是,首先找到所有的区域的链接;我们已经分析好了如何获取城市的盒子,那么接下来就是去获取城市的天气信息了。我们继续分析(具体分析过程可以看本视频教程)后发现,在table中,前面两个tr是表头,知识用来解释数据的,我们不需要,那么真正有用的数据是从第三个tr开始的。并且第三个tr的第 1 个td展示的是该省或者直辖市的名称,从第二个td开始才是真正展示该省份下这个城市的详细天气情况了,这里上一张图片分析一下:&并且,从第四个tr开始,下面的td全部展示的就是这个城市的信息了,而不包括省份的信息了,这里也用一张图片来说明这个问题:&所以综合以上的分析,我们就知道,省份名称是存储在table下的第三个tr下的第 0 个td下,而城市名字则要进行判断,如果是第三个tr,那么就是在第二个td,如果是从第四个开始,那么就是存储在第 0 个td下。而最高气温也要区分,第三个tr,存储在第 5 个td下,从第四个tr开始,则存储在第 4 个td下,那么我们也可以上一份源代码,看看如何获取的:conMidtab = soup.find('div', class_='conMidtab')conMidtab2_list = conMidtab.find_all('div', class_='conMidtab2')for x in conMidtab2_list:tr_list = x.find_all('tr')[2:]province = ''for index, tr in enumerate(tr_list):# 如果是第 0 个 tr 标签,那么城市名和省份名是放在一起的 & & & &min = 0if index == 0:td_list = tr.find_all('td')province = td_list[0].text.replace('\n', '')city = td_list[1].text.replace('\n', '') & & & & & &max = td_list[5].text.replace('\n', '') & & & &else:# 如果不是第 0 个 tr 标签,那么在这个 tr 标签中只存放城市名td_list = tr.find_all('td')city = td_list[0].text.replace('\n', '') & & & & & &max = td_list[4].text.replace('\n', '')TEMPERATURE_LIST.append({ & & & & & &'city': province+city, & & & & & &'min': min})数据显示:如果把所有数据都爬下来后,那么我们可以使用echarts-python把数据进行可视化,这部分内容比较简单,我就直接把我做的可视化的数据图给大家看下,具体的实现方式,大家可以观看我的视频教程,讲解非常详细:&写在最后:,都是通过表格的形式把属于该区域下的所有省份以及城市的天气信息列出来,一个省份的城市及其天气信息,然后右键点击审查元素,打开控制台后
为您推荐:
其他类似问题
您可能关注的内容
换一换
回答问题,赢新手礼包
个人、企业类
违法有害信息,请在下方选择后提交
色情、暴力
我们会通过消息、邮箱等方式尽快将举报结果通知您。}

我要回帖

更多关于 中国最热的城市 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信