利用requests模块爬取中央气象台网站的气象数据,用PySimpleGUI制作简单的交互页面。
一、对网站发送请求
以山西省太原市为例,对应页面网址如下:
http://www.nmc.cn/publish/forecast/ASX/taiyuan.html
而北京朝阳地区,对应页面网址如下:
http://www.nmc.cn/publish/forecast/ABJ/chaoyang.html
我们可以很轻易地发现其中地规律,想查询其他地区时,只要替换加粗部分即可。
获取url之后,就可对网址发送get请求,返回响应数据
url = 'http://www.nmc.cn/publish/forecast/A'+ province + '/' + city + '.html'
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36'
}
page_data = requests.get(url=url, headers=headers)
page_data.encoding = 'utf-8'
page_code = page_data.text
二、获取各类气象数据
通过分析,网站将近七天的气象数据分别存放在七个div标签里,因此可以先将七个div标签里的内容保存到列表中,再遍历列表,获取详细数据
在单个div标签中,存放有各种气象数据,通过xpath路径即可提取对应数据。需要注意的时,一天的数据分为上午和下午两个部分,如果在下午查询当天的数据,那么上午的气象数据将为空。
对应代码如下:
tree = etree.HTML(page_code)
div_list = tree.xpath('//*[@id="day7"]/div') # 获取数据所在<div> </div>
date_w = []
desc_m = []
windd_m = []
winds_m = []
high_tem = []
low_tem = []
desc_e = []
windd_e = []
winds_e = []
for div in div_list: # 将各项数据定位,保存到对应列表中
date_w_w = div.xpath('./div/div[1]/text()')[0]
desc_m_w = div.xpath('./div/div[3]/text()')[0]
windd_m_w = div.xpath('./div/div[4]/text()')[0]
winds_m_w = div.xpath('./div/div[5]/text()')[0]
high_tem_w = div.xpath('./div/div[6]/text()')[0]
low_tem_w = div.xpath('./div/div[7]/text()')[0]
desc_e_w = div.xpath('./div/div[9]/text()')[0]
windd_e_w = div.xpath('./div/div[10]/text()')[0]
winds_e_w = div.xpath('./div/div[11]/text()')[0]
date_w.append(date_w_w)
desc_m.append(desc_m_w)
windd_m.append(windd_m_w)
winds_m.append(winds_m_w)
high_tem.append(high_tem_w)
low_tem.append(low_tem_w)
desc_e.append(desc_e_w)
windd_e.append(windd_e_w)
winds_e.append(winds_e_w)
三、制作查询交互页面
查询设计流程如下:
1.输入省市信息;
2.选择查询日期;
3.输出查询结果
程序完整代码如下:
import requests
from lxml import etree
import PySimpleGUI as sg
import datetime
# pypinyin库可以把汉字转拼音(未安装此库)
sg.theme('SystemDefaultForReal') # 设置主题
province = sg.popup_get_text('输入查询省份大写首字母', keep_on_top=True)
city = sg.popup_get_text('输入查询城市拼音', keep_on_top=True)
url = 'http://www.nmc.cn/publish/forecast/A'+ province + '/' + city + '.html'
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36'
}
page_data = requests.get(url=url, headers=headers)
page_data.encoding = 'utf-8'
page_code = page_data.text
# print(page_data)
tree = etree.HTML(page_code)
div_list = tree.xpath('//*[@id="day7"]/div') # 获取数据所在<div> </div>
date_w = []
desc_m = []
windd_m = []
winds_m = []
high_tem = []
low_tem = []
desc_e = []
windd_e = []
winds_e = []
for div in div_list: # 将各项数据定位,保存到对应列表中
date_w_w = div.xpath('./div/div[1]/text()')[0]
desc_m_w = div.xpath('./div/div[3]/text()')[0]
windd_m_w = div.xpath('./div/div[4]/text()')[0]
winds_m_w = div.xpath('./div/div[5]/text()')[0]
high_tem_w = div.xpath('./div/div[6]/text()')[0]
low_tem_w = div.xpath('./div/div[7]/text()')[0]
desc_e_w = div.xpath('./div/div[9]/text()')[0]
windd_e_w = div.xpath('./div/div[10]/text()')[0]
winds_e_w = div.xpath('./div/div[11]/text()')[0]
date_w.append(date_w_w)
desc_m.append(desc_m_w)
windd_m.append(windd_m_w)
winds_m.append(winds_m_w)
high_tem.append(high_tem_w)
low_tem.append(low_tem_w)
desc_e.append(desc_e_w)
windd_e.append(windd_e_w)
winds_e.append(winds_e_w)
date_re = []
for i in date_w: # 删除日期列表中的空格,方便根据日期显示天气
date_re.append(i.replace(' ', ''))
print(date_re)
print(desc_m)
print(windd_m)
print(winds_m)
print(high_tem)
print(low_tem)
print(desc_e)
print(windd_e)
print(winds_e)
inquire_date = sg.popup_get_text('选择查询日期(支持未来七天):') # GUI选择日期
ti = datetime.datetime.now()
time_now = str(ti.month) + '月' + str(ti.day) + '日 ' + str(ti.hour) + '时' + str(ti.minute) + '分'
# 日期为今天时,上午和下午的日期显示有所区别(在下午5点以后,网站就不显示当天上午的天气了)
if inquire_date == date_re[0]:
if ti.hour < 17:
sg.popup(
'城市代码:'+ province + city,
'查询时间' + str(time_now),
'上午 天气:'+desc_m[0],
'上午 风力:'+windd_m[0],
'上午 风向:'+winds_m[0],
'上午 气温:'+high_tem[0],
'下午 气温:'+low_tem[0],
'下午 天气:'+desc_e[0],
'下午 风向:'+windd_e[0],
'下午 风力:'+winds_e[0],
font=('黑体',15),
keep_on_top=True)
else:
sg.popup('城市代码:'+ province + city,
'查询时间:'+str(time_now),
'下午 气温:'+low_tem[0],
'下午 天气:'+desc_e[0],
'下午 风向:'+windd_e[0],
'下午 风力:'+winds_e[0],
font=('黑体',15),
keep_on_top=True)
# 日期为其他天时
else:
date_index = date_re.index(inquire_date)
sg.popup('城市代码:'+ province + city,
'查询日期:' + date_re[date_index],
'上午 天气:' + desc_m[date_index],
'上午 风力:' + windd_m[date_index],
'上午 风向:' + winds_m[date_index],
'上午 气温:' + high_tem[date_index],
'下午 气温:' + low_tem[date_index],
'下午 天气:' + desc_e[date_index],
'下午 风向:' + windd_e[date_index],
'下午 风力:' + winds_e[date_index],
font=('黑体', 15),
keep_on_top=True)
四、实现效果展示