-
Notifications
You must be signed in to change notification settings - Fork 1
/
get_weather.py
166 lines (141 loc) · 11 KB
/
get_weather.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
# coding=utf-8
import json
import urllib.request
import time
import traceback
from urllib import error
import jieba
# 308个城市及其id
cityidlist = [["北京", [[54511, "北京"]]],
["天津", [[54527, "天津"]]],
["上海", [[58367, "上海"]]],
["重庆", [[57516, "重庆"]]],
["河北", [[53698, "石家庄"], [54534, "唐山"], [54401, "张家口"], [54515, "廊坊"], [53892, "邯郸"], [53798, "邢台"], [54616, "沧州"], [54702, "衡水"], [54602, "保定"], [54449, "秦皇岛"], [54423, "承德"]]],
["山西", [[53772, "太原"], [53782, "阳泉"], [53976, "晋城"], [53776, "晋中"], [53868, "临汾"], [53959, "运城"], [53882, "长治"], [53578, "朔州"], [53674, "忻州"], [53487, "大同"]]],
["内蒙古", [[53463, "呼和浩特"], [53446, "包头"], [54218, "赤峰"], [54102, "锡林浩特"], [53512, "乌海"], [53543, "鄂尔多斯"]]],
["辽宁", [[54342, "沈阳"], [54453, "葫芦岛"], [54346, "本溪"], [54324, "朝阳"], [54351, "抚顺"], [54249, "铁岭"], [54347, "辽阳"], [54471, "营口"], [54237, "阜新"], [54337, "锦州"], [54339, "鞍山"], [54497, "丹东"], [54662, "大连"]]], ["吉林", [[54161, "长春"], [54292, "延边"], [54172, "吉林市"], [54371, "白山"], [50936, "白城"], [54157, "四平"], [50946, "松原"], [54260, "辽源"]]],
["黑龙江", [[50953, "哈尔滨"], [54094, "牡丹江"], [50745, "齐齐哈尔"], [50854, "大庆"], [50774, "伊春"], [50884, "双鸭山"], [50775, "鹤岗"], [50978, "鸡西"], [50873, "佳木斯"], [50973, "七台河"], [50853, "绥化"], [50468, "黑河"], [50442, "大兴安岭"]]],
["江苏", [[58238, "南京"], [58259, "南通"], [58027, "徐州"], [58346, "宜兴"], [58248, "镇江"], [58145, "楚州"], [58246, "泰州"], [58245, "扬州"], [58343, "常州"], [58044, "连云港"], [58354, "无锡"]]],
["浙江", [[58457, "杭州"], [58450, "湖州"], [58549, "金华"], [58562, "宁波"], [58646, "丽水"], [58453, "绍兴"], [58633, "衢州"], [58452, "嘉兴"], [58660, "台州"], [58477, "舟山"], [58659, "温州"]]],
["安徽", [[58321, "合肥"], [58326, "巢湖"], [58221, "蚌埠"], [58424, "安庆"], [58311, "六安"], [58236, "滁州"], [58336, "马鞍山"], [58203, "阜阳"], [58433, "宣城"], [58429, "铜陵"], [58116, "淮北"], [58334, "芜湖"], [58102, "亳州"], [58122, "宿州"], [58224, "淮南"], [58437, "黄山"]]],
["福建", [[58847, "福州"], [58927, "龙岩"], [58834, "南平"], [58846, "宁德"], [58946, "莆田"], [59131, "泉州"], [58828, "三明"], [59126, "漳州"], [59134, "厦门"]]],
["江西", [[58606, "南昌"], [57786, "萍乡"], [58502, "九江"], [58623, "上饶"], [58627, "鹰潭"], [57793, "宜春"], [57993, "赣州"], [58527, "景德镇"]]],
["山东", [[54823, "济南"], [58024, "枣庄"], [54806, "聊城"], [54918, "曲阜"], [54915, "济宁"], [54938, "临沂"], [54906, "菏泽"], [54827, "泰安"], [54945, "日照"], [54736, "东营"], [54830, "淄博"], [54765, "烟台"], [54843, "潍坊"], [54774, "威海"], [54857, "青岛"]]],
["河南", [[57083, "郑州"], [57091, "开封"], [53898, "安阳"], [53982, "焦作"], [53990, "鹤壁"], [57171, "平顶山"], [58005,"商丘"], [54900, "濮阳"], [57178, "南阳"], [57089, "许昌"], [57297, "信阳"], [57051, "三门峡"], [57290, "驻马店"], [57195, "周口"], [53986, "新乡"], [57073, "洛阳"], [53978, "济源"]]],
["湖北", [[57494, "武汉"], [57498, "黄冈"], [57447, "恩施"], [57476, "荆州"], [57256, "十堰"], [57590, "咸宁"], [57278, "襄樊"], [57482, "孝感"], [57381, "随州"], [58407, "黄石"], [57377, "荆门"], [57496, "鄂州"], [57461, "宜昌"]]],
["湖南", [[57679, "长沙"], [57766, "邵阳"], [57662, "常德"], [57972, "郴州"], [57649, "吉首"], [57780, "株洲"], [57763, "娄底"], [57773, "湘潭"], [57674, "益阳"], [57866, "永州"], [57584, "岳阳"], [57872, "衡阳"], [57749, "怀化"], [57558, "张家界"]]],
["广东", [[59287, "广州"], [59312, "潮州"], [59278, "肇庆"], [59501, "汕尾"], [59293, "河源"], [59082, "韶关"], [59315, "揭阳"], [59117, "梅州"], [59485, "中山"], [59298, "惠州"], [59289, "东莞"], [59280, "清远"], [59476, "江门"], [59659, "茂名"], [59663, "阳江"], [59288, "佛山"], [59658, "湛江"], [59488, "珠海"], [59316, "汕头"], [59493, "深圳"]]],
["广西", [[59432, "南宁"], [59211, "百色"], [59046, "柳州"], [59265, "梧州"], [59453, "玉林"], [59254, "桂平"], [59065, "贺州"], [59632, "钦州"], [59249, "贵港"], [59635, "防城港"], [57957, "桂林"], [59644, "北海"]]],
["海南", [[59758, "海口"], [59845, "儋州"], [59856, "文昌"], [59981, "西沙"], [59948, "三亚"]]],
["四川", [[56294, "成都"], [57508, "泸州"], [57503, "内江"], [56571, "凉山"], [56172, "阿坝"], [57313, "巴中"], [57206, "广元"], [56386, "乐山"], [56196, "绵阳"], [56198, "德阳"], [56666, "攀枝花"], [56287, "雅安"], [56492, "宜宾"], [56396, "自贡"], [56146, "甘孜州"], [57328, "达州"]]],
["贵州", [[57816, "贵阳"], [57806, "安顺"], [57609, "赤水"], [57713, "遵义"], [57741, "铜仁"], [56693, "六盘水"], [57707, "毕节"], [57825, "凯里"], [57827, "都匀"]]],
["云南", [[56778, "昆明"], [56748, "保山"], [56768, "楚雄"], [56844, "德宏"], [56985, "红河"], [56951, "临沧"], [56643, "怒江"], [56964, "思茅"], [56994, "文山"], [56875, "玉溪"], [56586, "昭通"], [56543, "迪庆"], [56651, "丽江"], [56959, "西双版纳"], [56751, "大理"]]],
["西藏", [[55591, "拉萨"], [56137, "昌都"], [55228, "阿里"], [55299, "那曲"], [55578, "日喀则"], [55598, "山南"], [56312, "林芝"]]],
["陕西", [[57036, "西安"], [53955, "韩城"], [57245, "安康"], [57127, "汉中"], [57016, "宝鸡"], [57048, "咸阳"], [53646, "榆林"], [57045, "渭南"], [57143, "商洛"], [53947, "铜川"], [53845, "延安"]]],
["甘肃", [[52889, "兰州"], [52896, "白银"], [53829, "庆阳"], [52533, "酒泉"], [57006, "天水"], [52679, "武威"], [52652, "张掖"], [56080, "甘南"], [52984, "临夏"], [53915, "平凉"], [52995, "定西"]]],
["青海", [[52866, "西宁"], [52853, "海北"], [52856, "海南州"], [52737, "海西"], [52974, "黄南"], [56043, "果洛"], [56029, "玉树"]]],
["宁夏", [[53614, "银川"], [53817, "固原"], [53704, "中卫"]]],
["新疆", [[51463, "乌鲁木齐"], [51076, "阿勒泰"], [51628, "阿克苏"], [51368, "昌吉"], [52203, "哈密"], [51828, "和田"], [51709, "喀什"], [51243, "克拉玛依"], [51356, "石河子"], [51133, "塔城"], [51656, "库尔勒"], [51573, "吐鲁番"], [51431, "伊犁"]]],];
# urllib.request.install_opener(cityidlist)
# 从cityidlist中获取城市和id,构成列表city_id
def try_weather(question):
words = jieba.cut_for_search(question)
weather = Weather()
for word in words:
weather.put(word)
if weather.satisfy():
return weather.get_weather()
return None
class Weather(object):
def __init__(self):
self.city = None
self.trigger = False
def put(self, word):
if word in city_list:
self.city = word
if word == "天气":
self.trigger = True
def satisfy(self):
return self.trigger and self.city is not None
def clear(self):
self.__init__()
def get_weather(self):
if not self.satisfy():
raise ValueError("Weather pre-condition not satisfied")
return get_weather(self.city)
weather = Weather()
city_id = []
for i in cityidlist:
for j in i:
if isinstance(j, list):
for k in j:
city_id.append(k)
# 把城市和id分成两个列表city_list和id_list
id_city = []
for a in city_id:
if isinstance(a, list):
for p in a:
id_city.append(p)
id_list = id_city[::2] # id列表
city_list = id_city[1::2] # 城市列表
# 匹配城市,返回id
def get_city_id(city):
for t in range(len(city_list)):
if city == "".join(city_list[t]):
return id_list[t]
# 模拟成浏览器
headers = {"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
"Accept-Encoding": "gbk,utf-8,gb2312",
"Accept-Language": "zh-CN,zh;q=0.8",
"User-Agent": "Mozilla/5.0(Windows NT 10.0; WOW64) AppleWebKit/537.36(KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36",
"Connection": "keep-alive"}
opener = urllib.request.build_opener()
head_all = []
for key, value in headers.items():
item = (key, value)
head_all.append(item)
opener.add_headers = head_all
# 安装不同的opener对象作为urlopen()使用的全局opener
urllib.request.install_opener(opener)
# 获取天气数据,返回天气数据字典
def get_weather(city):
try:
url = "http://www.nmc.cn/f/rest/real/"+str(get_city_id(city))
stdout = urllib.request.urlopen(url)
weatherInfo = stdout.read().decode("utf-8")
jsonData = json.loads(weatherInfo)
# 添加数据
weather_dict = {'城市:': jsonData["station"]["city"],
'数据更新时间:': jsonData["publish_time"],
'天气:': jsonData["weather"]["info"],
'风向:': jsonData["wind"]["direct"],
'风速:': str(jsonData["wind"]["speed"]) + "m/s",
'实时温度:': str(jsonData["weather"]["temperature"]) + "℃",
'相对湿度:': str(int(jsonData["weather"]["humidity"])) + "%"}
return weather_dict
except error.URLError as e:
print("获取天气状况数据出现URL_ERROR!一分钟后重试……")
if hasattr(e, "code"):
print(e.code)
if hasattr(e, "reason"):
print(e.reason)
time.sleep(60)
# 出现异常则过一段时间重新执行此部分
return get_weather(city)
except Exception as e:
print("获取天气状况数据出现EXCEPTION!十秒钟后重试……")
print("Exception:" + str(e))
traceback.print_exc() # 获得错误行数
time.sleep(10)
# 出现异常则过一段时间重新执行此部分
return get_weather(city)
# 读取城市名称,与city_list中的每一项进行匹配,若匹配成功,输出对应的天气数据字典,否则,再次读取
def print_weather():
while (True):
print("请输入有效天气查询城市:")
str_city = input()
for each in city_list:
if str_city == each:
print(get_weather(str_city))
if __name__ == '__main__':
print_weather()