使用 Python获取中国天气网数据
一、中国天气网API数据
写这个文章的灵感就是因为西安的鬼天气,我突然想去查查西安这几天的天气怎么样,果断就找到了中
国天气网。突发奇想,诶,这个网站的天气数据可不可以用 Python来获取!这个网站是不是有天气数据
接口,还是需要来解析返回的网页内容。
首先是要知道中国天气网的数据接口,这个貌似很好找,随便Baidu了一下就出结果了:
• 从访问 http://61.4.185.48:81/g/可以根据访问时候的 IP地址给出所在城市的 ID,这个 ID不知道
是怎编码的。
• 利用上面获取的编码,访问 http://m.weather.com.cn/data/101110101.html就可以获取到天气数
据,这里的 101110101是西安的城市 ID。
可以试下,出来的数据结果列在下面,关于各自代
表
关于同志近三年现实表现材料材料类招标技术评分表图表与交易pdf视力表打印pdf用图表说话 pdf
的意思,俄,好简单。看到返回的数据貌似是字典,
哎呀可是是字符串,怎么转换字典数据哎。其实这些数据是可以用 Python的 json模块解析的。
{"weatherinfo":{
"city":"西安", #城市名
"city_en":"xian", #这是拼音
"date_y":"2012年 6月 24日", #这是日期
"date":"",
"week":"星期日", #这是星期
"fchh":"18",
"cityid":"101110101", #城市 ID
"temp1":"24 ~32 ", ℃ ℃ #查询当天的天气
"temp2":"23 ~26 ", ℃ ℃ #这是第二天的
"temp3":"22 ~25 ", ℃ ℃ #下面类推
"temp4":"21 ~27 ",℃ ℃
"temp5":"22 ~27 ",℃ ℃
"temp6":"23 ~25 ",℃ ℃
"tempF1":"75.2 ~89.6 ", ℉ ℉ #是这几天温度的华氏温度
"tempF2":"73.4 ~78.8 ",℉ ℉
"tempF3":"71.6 ~77 ",℉ ℉
"tempF4":"69.8 ~80.6 ",℉ ℉
"tempF5":"71.6 ~80.6 ",℉ ℉
"tempF6":"73.4 ~77 ",℉ ℉
"weather1":"阴转小雨", #是这几天的天气描述
"weather2":"中雨转小雨",
"weather3":"小雨",
"weather4":"小雨转阴",
"weather5":"小雨",
"weather6":"小雨转阴",
"img1":"2","img2":"7","img3":"8","img4":"7","img5":"7","img6":"99","img7":"7","img8":"2","im
g9":"7","img10":"99","img11":"7","img12":"2","img_single":"7",
"img_title1":"阴","img_title2":"小雨","img_title3":"中雨","img_title4":"小雨","img_title5":"小
雨","img_title6":"小雨","img_title7":"小雨","img_title8":"阴","img_title9":"小雨","img_title10":"小
雨","img_title11":"小雨","img_title12":"阴","img_title_single":"小雨",
#这是上面几天所对应的图片 ID,一天对应两个,正好是 12个,随后一个 img_title_single估计是单独
显示用的天气图标
"wind1":"微风","wind2":"微风","wind3":"旋转风小于 3级","wind4":"旋转风小于 3级","wind5":"旋转
风小于 3级","wind6":"旋转风小于 3级","fx1":"微风","fx2":"微风","fl1":"小于 3级","fl2":"小于 3
级","fl3":"小于 3级","fl4":"小于 3级","fl5":"小于 3级","fl6":"小于 3级",
#这是几天的风里描述信息,不知道为啥中间插两个 fx1和 fx2
"index":"炎热","index_d":"天气炎热,建议着短衫、短裙、短裤、薄型T恤衫、敞领短袖棉衫等清凉夏
季服装。","index48":"暖","index48_d":"较凉爽,建议着长袖衬衫加单裤等春秋过渡装。年老体弱者宜
着针织长袖衬衫、马甲和长裤。","index_uv":"弱","index48_uv":"最弱","index_xc":"不
宜","index_tr":"适宜","index_co":"较不舒适",
#这是天气描述和穿衣建议,同样还有紫外线(UV)、洗车(XC)、旅游(TR)和感觉吧应该
(CO),确实是较不舒适
"st1":"30","st2":"24","st3":"22","st4":"22","st5":"23","st6":"20",
"index_cl":"较不宜","index_ls":"不宜","index_ag":"不易发"}}
#最后这些东西我也搞不懂是神马
二、一个小例子
知道了如何获取数据,以及数据返回的信息,那么这个程序应该是很简单就写出来了。
但是再写程序之前,我还要规划一下这个程序都包含哪些功能,还有数据怎么组织这些问
题
快递公司问题件快递公司问题件货款处理关于圆的周长面积重点题型关于解方程组的题及答案关于南海问题
。
• 首先,程序应该可以自动获取到所在城市,并从网上得到天气数据;
• 第二,还得要能够自己指定城市名称,得到城市 ID 并获取天气数据;
• 第三,返回的数据要能够以简单易懂的形式从外部访问到;
• 第四,程序需要能够以一定的格式简单汇报出几天内的天气;
• 第五,程序要能够接受命令行参数,汇报指定城市的天气。
程序需求分析好了,下面就决定下程序的结构:
• 一个获取城市 ID的函数
• 一个获取天气信息的函数
• 一个以一定格式存储天气数据的类
• 一个能够简单汇报天气信息的函数
当然程序不能要先执行几个函数才能够输出天气数据,要能够有一个直接汇报天气的函数,只需要执行
类似于weather.Report()这样的代码就能够得到简单的天气预报,或者直接双击执行程序就能够输出天
气信息。
一切的准备就绪了,开始写程序。
#首先导入一下 必须的模块
import sys, urllib2, json, codecs, time
#sys模块用来获取命令行参数,用来获取城市名,也
许可
商标使用许可商标使用许可商标使用许可商标使用许可商标使用许可
以一次获取很多城市名
#urllib2模块用来访问网络,json用来解析返回数据
#codecs模块用来打开城市编码文件
#time模块只用来是程序暂停几秒,然后再继续
#下面定义获取城市 ID的函数
#这个 baidu的编辑器到底该怎样贴代码,这缩进虽然都对,但是看着好难看!
def get_cityid(city = None):
if city == None:
id_url = 'http://61.4.185.48:81/g/'
id_data = urllib2.urlopen(id_url)
city_id = id_data.readline().split(';')[1].split('=')[1]
else:
idfile = open('city_id.txt', 'r')
for line in idfile:
line = line.decode('gbk').encode('utf-8')
if city in line:
city_id = line.split(',')[0]
break
else:
city_id = None
if city_id == None:
raise ValueError('City Name Incorrect')
return city_id
#这段代码可以实现自动获取城市 ID的功能,这时候输入 city为None;如果输入了 city字符串,那么
函数就会进入 city_id.txt这个文件去找对应的城市编码。city_id.txt这个文件是GBK编码的,所以在查
找之前需要进行编码转换。
#其中 http://61.4.185.48:81/g/的返回结果为“var ip="61.150.43.40";var
id=101110101;if(typeof(id_callback)!="undefined"){id_callback();}”没有端段的引号。先对这个字符
串使";";分割,得到第二个元素为"var id=101110101",接下来使用"="分割,得到的第二个元素就是城
市 ID了。
#city_id.txt文件中每一行为一个城市,存储格式为 101110101,西安。
#下面定义获取天气的函数
def get_weather(city_id):
ids = str(city_id)
base_url = 'http://m.weather.com.cn/data/'
city_url = base_url + ids + '.html'
try:
data_return = urllib2.urlopen(city_url)
except urllib2.URLError:
raise ValueError('City ID Not Correct')
weather_data = [i for i in data_return]
data = json.loads(weather_data[0])
v = Weather(data)
return v
#这个函数接受 city_id 作为字符串参数,以免发生意外就在函数的第一行做了强制类型转换。
#然后就是常见的求的完整的URL,再使用 urllib2 进行访问,获取返回结果了。
#这个函数的返回就是天气网返回的完整的数据,这些数据将会在天气数据类的 init 函数中做解析。
#下面就是天气数据类的定义
class Weather(object):
def __init__(self, data):
data = data['weatherinfo']
self.city = data['city']
self.id = data['cityid']
self.date = ' '.join([data['date_y'], data['week']])
t1 = ' '.join([data['temp1'], data['weather1']])
t2 = ' '.join([data['temp2'], data['weather2']])
t3 = ' '.join([data['temp3'], data['weather3']])
t4 = ' '.join([data['temp4'], data['weather4']])
t5 = ' '.join([data['temp5'], data['weather5']])
t6 = ' '.join([data['temp6'], data['weather6']])
self.weather = [t1, t2, t3, t4, t5, t6]
self.suggest = data['index_d']
self.original = data
def report(self):
days = [u'今天', u'明天', u'后天']
print ' '
print self.city, self.date
print '-'*26
for i in range(3):
print days[i] + u':' + self.weather[i]
print '-'*26
print self.suggest
#给这个类起个名字叫 Weather,它的父类是 python所以类的父类 object。然后定义__init__函数,这
个函数是在该类实例化的时候由 python自动调用的,用来初始化一些变量,我就用这个函数来解析传递
进来的天气数据。
#__init__函数接受两个参数,一个是 self,一个是 data,类
方法
快递客服问题件处理详细方法山木方法pdf计算方法pdf华与华方法下载八字理论方法下载
函数至少需要一个参数为 self,为解释
器自动传递的。也就是说在调用类方法函数的时候,不用指定任何参数解释器自动的把调用函数的类实
例名称作为第一个参数 self 传递进去。所以在定义类方法的时候至少要指定一个参数为 self,无论在函
数中到底用不用它。另外,如果需要函数内的变量在整个类范围内都能够被访问,就需要写成 self.XXX
的样子,这其实是类属性。否则的话定义的变量只是在函数内起作用。
#根据上一篇文章的描述,不难找出如何从那么一堆数据中提取出需要的数据,无非就是写字符串处理。
#同时还定义了一个 report 作为类方法,用来简单汇报一些天气信息。这样在程序的Report 函数中就可
以不用再编写冗长的输出格式代码了。当然可以改汇报的天数,只需要将 for i in range(3):中的 3 改成其
他数就可以了,当然同时还得在 days列表中添加以后几天的描述,比如大后天,大大后天,大大大后天
……
#下面定义的是程序的Report 函数
def Report(city='LOCAL'):
if city == 'LOCAL':
city_id = get_cityid()
weather_data = get_weather(city_id)
weather_data.report()
else:
city = city.decode('gbk').encode('utf-8')
city_id = get_cityid(city)
weather_data = get_weather(city_id)
weather_data.report()
#这个函数其实就是一个程序集,将上面定义的函数组织起来。
#函数接受城市名作为参数,也可以不提供,这将默认自动获取所在地的天气。
#首先使用 get_id 函数获取城市 ID,当然输入参数和没有输入参数是不一样的。
#接着根据获取的 ID获得天气数据,实例化一个Weather数据类,也就是提取出一些简单的数据,最后
在使用数据类的Report 方法简单汇报天气。
#当然最后还要实现能够接受命令行参数,也可以直接双击运行
if __name__ == '__main__':
if len(sys.argv) == 1:
import time
Report()
time.sleep(5)
sys.exit(0)
else:
for city in sys.argv[1:]:
Report(city)
#每一个脚本运行的时候都会产生一个__name__变量,这个变量在程序被导入的时候为导入程序的名字,
如果程序是被直接运行的,不管事双击还是命令行运行,__name__变量的值就为'__main__',这样就保
证程序在导入的时候不会再运行一次产生一些干扰数据。
#sys.argv 会返回一个列表,为程序执行的参数,其中第一个参数为程序文件的文件名,也就是说
sys.argv 至少有一个值。如果 sys.argv的长度为 1就证明,用户并没有传进任何参数,那么就只要获取
所在地城市 ID,汇报天气就OK了。
#如果 sys.argv长度不为 1,就说明程序至少获取到了一个城市名参数,那么就遍历所有的城市名参数,
输出对应的天气预报。
至此,整个程序功能都实现了。完整的程序代码如下,没有注释:
# -*- coding:utf-8 -*-
import sys
class Weather(object):
def __init__(self, data):
data = data['weatherinfo']
self.city = data['city']
self.id = data['cityid']
self.date = ' '.join([data['date_y'], data['week']])
t1 = ' '.join([data['temp1'], data['weather1']])
t2 = ' '.join([data['temp2'], data['weather2']])
t3 = ' '.join([data['temp3'], data['weather3']])
t4 = ' '.join([data['temp4'], data['weather4']])
t5 = ' '.join([data['temp5'], data['weather5']])
t6 = ' '.join([data['temp6'], data['weather6']])
self.weather = [t1, t2, t3, t4, t5, t6]
self.suggest = data['index_d']
self.original = data
def report(self):
days = [u'今天', u'明天', u'后天']
print ' '
print self.city, self.date
print '-'*26
for i in range(3):
print days[i] + u':' + self.weather[i]
print '-'*26
print self.suggest
def get_cityid(city = None):
import urllib2
if city == None:
id_url = 'http://61.4.185.48:81/g/'
id_data = urllib2.urlopen(id_url)
city_id = id_data.readline().split(';')[1].split('=')[1]
else:
import codecs
idfile = open('city_id.txt', 'r')
for line in idfile:
line = line.decode('gbk').encode('utf-8')
if city in line:
city_id = line.split(',')[0]
break
else:
city_id = None
if city_id == None:
raise ValueError('City Name Incorrect')
return city_id
def get_weather(city_id):
import json
import urllib2
ids = str(city_id)
base_url = 'http://m.weather.com.cn/data/'
city_url = base_url + ids + '.html'
try:
data_return = urllib2.urlopen(city_url)
except urllib2.URLError:
raise ValueError('City ID Not Correct')
weather_data = [i for i in data_return]
data = json.loads(weather_data[0])
v = Weather(data)
return v
def Report(city='LOCAL'):
if city == 'LOCAL':
city_id = get_cityid()
weather_data = get_weather(city_id)
weather_data.report()
else:
city = city.decode('gbk').encode('utf-8')
city_id = get_cityid(city)
weather_data = get_weather(city_id)
weather_data.report()
if __name__ == '__main__':
if len(sys.argv) == 1:
import time
Report()
time.sleep(5)
sys.exit(0)
else:
for city in sys.argv[1:]:
Report(city)
#完整的程序和
设计
领导形象设计圆作业设计ao工艺污水处理厂设计附属工程施工组织设计清扫机器人结构设计
时候不太一太样,我改变了模块的导入位置,也就是说在需要使用到模块的地方导入,
这样能够增加程序的运行速度。
使用Python获取中国天气网数据
一、中国天气网API数据
二、一个小例子