需求描述
打开天气网,点击上方城市名称,再点击“15天天气”,进入如下页面。这里以天津为例。
可以看到,这里是有未来15天的天气和气温状况的。我们要做的就是把每天的最高和最低气温爬取下来,并做成折线图的形式。
需求分析
任意选取一天的气温,单击鼠标右键检查元素(这里我使用的是Firefox浏览器,不同浏览器可能略有不同)进入查看器。我们得到了下图所示的HTML结构。
可以看出,每一天的天气信息都存储在class
属性为table_day
的div
标签之中,而气温信息则存储在div
标签内部的class
属性为temp
的li
标签之中。那么,我们只需要定位到这个标签,对该标签内的文本进行提取,即可获得这15天的最高气温和最低气温。
代码实现
首先我们需要导入相关的模块。
import re
import requests
from pyecharts import Line
from bs4 import BeautifulSoup
对网站发起请求,获取页面的数据。即进行UA伪装后对URL发起GET请求。
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:75.0) Gecko/20100101 Firefox/75.0'}
url = 'https://www.tianqi.com/tianjin/15/'
response = requests.get(url=url, headers=headers)
page_text = response.text
筛选出有关气温信息的内容。
在筛选出class
属性为temp
的li
标签的文本之后,我使用了正则表达式来分离最高气温值与最低气温值,并保存到对应的列表中。以波浪线作为切入点,波浪线前的数字即为最低气温,波浪线后的数字即为最高气温。获取正则匹配的文本之后,对字符串进行切片,然后使用eval()
函数将其转化为数字形式存放在列表中。
soup = BeautifulSoup(page_text, 'html.parser')
div_list = soup.find_all(class_='box_day')
table_day_list = div_list[0].find_all(class_='table_day')
low_temp = []
high_temp = []
for i in range(len(table_day_list)):
li = table_day_list[i].find(class_='temp').text
low = eval(re.search(r'(\d*)~', li).group()[:-1])
low_temp.append(low)
high = eval(re.search(r'~(\d*)', li).group()[1:])
high_temp.append(high)
最后一步,使用pyecharts模块进行数据可视化。
这里我偷了个懒,attr
列表中的内容是可以在筛选数据的过程中一并获取的。写代码的时候为了方便就自己写了attr
列表。这样写有个缺点,就是在做下一次的15天气温预报的时候需要手动更改attr
列表中的元素。
attr = ['2020-04-16', '2020-04-17', '2020-04-18', '2020-04-19', '2020-04-20', '2020-04-21', '2020-04-22', '2020-04-23',
'2020-04-24', '2020-04-25', '2020-04-26', '2020-04-27', '2020-04-28', '2020-04-29', '2020-04-30']
line = Line('天津未来15天的气温走势', '日期:2020-04-16至2020-04-30')
line.add('日最低气温', attr, low_temp, is_smooth=False, mark_point=['min'], mark_line=['average'])
line.add('日最高气温', attr, high_temp, is_smooth=False, mark_point=['max'], mark_line=['average'])
line.render('天津未来15天气温走势图.html')
完整代码及结果展示
该样例的完整代码如下:
#!/usr/bin/env python3
import re
import requests
from pyecharts import Line
from bs4 import BeautifulSoup
# 爬取天气网天津2020-04-16至2020-04-30的最高和最低气温
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:75.0) Gecko/20100101 Firefox/75.0'}
url = 'https://www.tianqi.com/tianjin/15/'
response = requests.get(url=url, headers=headers)
page_text = response.text
# 筛选出所需数据
soup = BeautifulSoup(page_text, 'html.parser')
div_list = soup.find_all(class_='box_day')
table_day_list = div_list[0].find_all(class_='table_day')
low_temp = []
high_temp = []
for i in range(len(table_day_list)):
li = table_day_list[i].find(class_='temp').text
low = eval(re.search(r'(\d*)~', li).group()[:-1])
low_temp.append(low)
high = eval(re.search(r'~(\d*)', li).group()[1:])
high_temp.append(high)
# 数据可视化
attr = ['2020-04-16', '2020-04-17', '2020-04-18', '2020-04-19', '2020-04-20', '2020-04-21', '2020-04-22', '2020-04-23',
'2020-04-24', '2020-04-25', '2020-04-26', '2020-04-27', '2020-04-28', '2020-04-29', '2020-04-30']
line = Line('天津未来15天的气温走势', '日期:2020-04-16至2020-04-30')
line.add('日最低气温', attr, low_temp, is_smooth=False, mark_point=['min'], mark_line=['average'])
line.add('日最高气温', attr, high_temp, is_smooth=False, mark_point=['max'], mark_line=['average'])
line.render('天津未来15天气温走势图.html')
运行这个程序可以得到一个HTML文件。使用浏览器打开,得到下图所示的结果: