本文爬取的内容都是就是当天全国所有城市的最高气温以及最低气温。
中国天气网首先将各个省份按照地区划分,共分为华北,东北,华东,华中,华南,西北,西南,港澳台。不同地区有不同的url。 比如:华北地区的url就是:http://www.weather.com.cn/textFC/hb.shtml 东北地区的url就是:http://www.weather.com.cn/textFC/db.shtml 华北地区有:北京,天津,河北,山西,内蒙古 这几个省份,下图1 展示了华北地区的天气数据 东北地区有:黑龙江,辽宁,吉林这几个省份,下图2展示了东北地区的天气数据
从下图3可以看出所有的天气数据都按照省份分类展示个一个个表格中,一个表格展示一个省份的数据,表格中每行展示各省份下面的地级市的数据。
每个省份的所有数据都通过一个表格来展示,所有表格的格式都一样。所以我们只需要按照规则匹配提取出我们想要的数据即可。
通过xpath匹配出的结果如下图4所示。
xpath表达式的说明://div[@class="conMidtab"][1]//table//tr[position()>2]
这个表达式看着有点儿小复杂。
首先最外层的 <div class="conMidtab"></div>
展示了每天的数据,每周有七天,所以一共有七个<div class="conMidtab"></div>
这里我们去的是今天的数据,所有代码就是//div[@class="conMidtab"][1]
接着里层的<div class=conMidtab2></div>
就是包装了每个table。这里华北地区一共有五个省份,所有一共有五个<div class="conMidtab2"></tab>
在接着就是包装数据的table。
table的前两行是表头,不是我们想要的数据,所以就需要将它们剔除掉。//tr[position()>2]
,所有代码就是这样写。
这里我们需要提取城市,最高气温,最低气温。三者的表达式类似。这里以提取城市的表达式为例进行说明。
因为前面2.1这一步我们已经将数据所在行提取出来了,所以这里只需要根据行来找单元格。城市这个单元格在第一个。所以就是/td[1]
最终提取页面数据的代码就是:
def parse_page(url):
resp = requests.get(url, headers=header)
html = etree.HTML(resp.content.decode('utf-8'))
tr_elements = html.xpath('//div[@class="conMidtab"][1]//table//tr[position()>2]')
for tr_element in tr_elements:
# 获取城市
city_data = tr_element.xpath('./td[1]//text()')[1].strip()
# 获取最低气温
min_temp = tr_element.xpath('./td[last()-1]//text()')[0].strip()
# 获取最高气温
max_temp = tr_element.xpath('./td[last()-4]//text()')[0].strip()
data_dict = {'city': city_data, 'min_temp': int(min_temp), 'max_temp': int(max_temp)}
ALL_DATA.append(data_dict)
前面我们已经将气温数据都通过字典的形式存在了ALL_DATA列表中。现在只需要对列表进行一个简单的排序即可。
max_temps_list = sorted(ALL_DATA, key=lambda data: data['max_temp'], reverse=True)
通过lambda表达式提取出最高气温max_temp,将其作为排序的key。因为sorted默认是正序排列的,所以需要将列表翻转,将参数reverse设置为True。同时,使用sorted方法的好处就是该方法不会改变原有列表ALL_DATA的内容结构。
表达式lambda data: data['max_temp']
相当于下面这个函数
def sort_key(data):
max_temp = data['max_temp']
return max_temp
这里可视化展示用到了pyecharts库。
pyecharts库的官方地址:https://github.com/pyecharts/pyecharts
pip install pyecharts -U
这里我们期望使用pyecharts库展示一个柱形图,这个库的使用比较简单,这里就直接贴代码了。首先实例化一个Bar对象,然后设置横坐标add_xaxis,将横坐标设置为城市;接着就是设置纵坐标,将纵坐标设置为add_yaxis最高气温。
from pyecharts.charts import Bar
from pyecharts import options as opts
max_temps_list = sorted(ALL_DATA, key=lambda data: data['max_temp'], reverse=True)
data_list = max_temps_list[0:10]
bar2 = Bar()
cities = list(map(lambda x: x['city'], data_list))
max_temps = list(map(lambda y: y['max_temp'], data_list))
bar2.add_xaxis(cities)
bar2.add_yaxis('最高气温', max_temps)
bar2.set_global_opts(title_opts=opts.TitleOpts(title="中国天气最高气温排行榜"))
bar2.render("max_temp.html")
最后一步就是将图表写到min_temp.html文件中。来看看最终的效果吧。
# -*- utf-8 -*-
"""
@url: https://blog.csdn.net/u014534808
@Author: 码农飞哥
@File: weather_main.py
@Time: 2021/12/5 07:36
@Desc: 爬取天气信息
"""
import requests
from lxml import etree
from pyecharts.charts import Bar
from pyecharts import options as opts
header = {
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.55 Safari/537.36"
}
# 统计列表
districts = ['hb', 'db', 'hd', 'hz', 'hn', 'xb', 'xn', 'gat']
ALL_DATA = list()
def parse_page(url):
resp = requests.get(url, headers=header)
html = etree.HTML(resp.content.decode('utf-8'))
tr_elements = html.xpath('//div[@class="conMidtab"][1]//table//tr[position()>2]')
for tr_element in tr_elements:
# 获取城市
city_data = tr_element.xpath('./td[1]//text()')[1].strip()
# 获取最低气温
min_temp = tr_element.xpath('./td[last()-1]//text()')[0].strip()
# 获取最高气温
max_temp = tr_element.xpath('./td[last()-4]//text()')[0].strip()
data_dict = {'city': city_data, 'min_temp': int(min_temp), 'max_temp': int(max_temp)}
ALL_DATA.append(data_dict)
def main():
# 解析页面
for district in districts:
url = 'http://www.weather.com.cn/textFC/{0}.shtml'.format(district)
parse_page(url)
# 分析数据
# 根据最低气温进行排序
min_temps_list = sorted(ALL_DATA, key=lambda data: data['min_temp'])
data_list = min_temps_list[0:10]
# 安装pyecharts pip install pyecharts
bar = Bar()
cities = list(map(lambda x: x['city'], data_list))
min_temps = list(map(lambda x: x['min_temp'], data_list))
bar.add_xaxis(cities)
bar.add_yaxis('最低气温', min_temps)
bar.set_global_opts(title_opts=opts.TitleOpts(title="中国天气最低气温排行榜"))
bar.render("min_temp.html")
max_temps_list = sorted(ALL_DATA, key=lambda data: data['max_temp'], reverse=True)
data_list = max_temps_list[0:10]
bar2 = Bar()
cities = list(map(lambda x: x['city'], data_list))
max_temps = list(map(lambda y: y['max_temp'], data_list))
bar2.add_xaxis(cities)
bar2.add_yaxis('最高气温', max_temps)
bar2.set_global_opts(title_opts=opts.TitleOpts(title="中国天气最高气温排行榜"))
bar2.render("max_temp.html")
if __name__ == '__main__':
main()
本文通过爬取中国天气网的天气预报数据并将其可视化展示。从中学习到了xpath表达式的使用,pyecharts库的使用等知识点。希望对读者朋友们有所帮助