- 大纲
- 项目介绍:利用python请求中国天气网的接口,以获得输入城市的天气情况
- 输入:地级市城市名称,如北京;输出:城市的天气包括最高、最低气温和状况,如 16℃ ~ 28℃,阵雨转晴
- 难点:中国天气网接口只能接收城市名称对应的城市编号来查询;解决方案-爬取各城市对应的城市编号,并保存为字典用来调用
2. 获取城市编号
'''
author:jason date:190711
作用:提取城市对应的编号
目标对象示例:<a href="http://www.weather.com.cn/weather/101050101.shtml" target="_blank">哈尔滨</a></td>
得到结果示例:城市名称-哈尔滨 和城市编号-101050101 2个字段
背景:调用天气预报接口时,输入是城市对应的城市编号,而用户通常只会输入城市名称,如上海
用到的知识点:a. pyquery库请求和解析源码,获取对应的字段;b. 字典的使用
'''
# -*- coding: utf-8 -*-
from pyquery import PyQuery as pq
#可通过http://www.weather.com.cn/textFC/hb.shtml 查看当前天气,源码可查看到城市编号
base_url = 'http://www.weather.com.cn/textFC/{}.shtml'
#sites 各个区简称,如hb代表华北,拼接到base_url形成完成链接,可访问
sites = ['hb', 'db', 'hd', 'hz', 'hn', 'xb', 'xn', 'gat']
#本地调试时需要先转码再测试
#doc = pq(filename = 'test.html')
#with open('test.html',encoding='utf-8') as f:
# text = f.read()
#doc = pq(doc)
##print(doc('.conMidtab a'))
#type(doc('.conMidtab a'))
def City2Id():
#CityIdTbl:字典型,用来保存城市名称和对应的城市编号,如'北京': '101010100'
CityIdTbl = {}
for i in sites:
#读取url,并用utf-8编码以兼容中文
doc = pq(base_url.format(i),encoding = 'utf-8')
#解析class="conMidtab"节点下的a节点并调用items方法以实现遍历,示例如下
#<div class="conMidtab">
#<a href="http://www.weather.com.cn/weather/101050101.shtml" target="_blank">哈尔滨</a></td>
list0 = doc('.conMidtab a').items()
for lst in list0:
#条件1:lst.text() in ( '返回顶部','详情') 剔除返回顶部','详情'类型
#条件2:lst.text() in CityIdTbl.keys() 避免重复的城市再次计入,setdefault也可刷新
#条件3:len(str(lst.attr('href')))< 49 剔除链接中无ID的场景
#如<a href="/textFC/hongkong.shtml" target="_blank">香港</a>
if lst.text() in ( '返回顶部','详情',CityIdTbl.keys(),'') or len(str(lst.attr('href')))< 49:
#or len(str(lst.attr('href')))< 49 :
continue
else:
city_name = lst.text()
city_no = lst.attr('href')
CityIdTbl.setdefault(city_name,city_no[34:43])
return CityIdTbl
if __name__ == '__main__':
print(City2Id())
3. 获取城市的天气
'''
author:jason date:190711
作用:提取城市对应的天气包括最高、最低气温和状况
得到结果示例:阵雨转晴 16℃ ~ 28℃
背景:调用天气预报接口时,输入是城市对应的城市编号,而用户通常只会输入城市名称,如上海
用到的知识点:a. url请求库requests的使用,获取对应的字段;b. 利用break退出while,避免死循环
'''
import requests
from cityid import City2Id
url = 'http://www.weather.com.cn/data/cityinfo/{}.html'
#请求天气网接口,并返回响应内容的json格式
def Responce(loc='101010100'):
req = requests.get(url.format(loc))
req.encoding = 'utf-8'
return req.json().get('weatherinfo')
#解析获取目标城市的最高、最低气温
def ParseTemp(dict0):
return dict0.get('temp1') + ' ~ ' + dict0.get('temp2')
#解析获取目标城市的天气状态
def WeatherStatus(dict0):
return dict0.get('weather')
if __name__ == '__main__':
CityIdTbl = City2Id()
while True:
city = input('请输入你要查询当日天气的城市名称(中文):')
if CityIdTbl.get(city):
print(city)
print(WeatherStatus(Responce(CityIdTbl.get(city))))
print(ParseTemp(Responce(CityIdTbl.get(city))))
break
elif city == '0':
print('感谢使用,88')
break
else:
print('你输入的城市名称:%s 有误,请重新输入n强制退出请输入0' %city)
4. 参考文档
项目来源和参考-crossin编程教室mp.weixin.qq.com 华北地区天气预报www.weather.com.cn 中国天气网-城市(北京城市示例)www.weather.com.cn 爬取中国天气网获取全国城市编码并存入mysql数据库blog.csdn.net