九、Python数据分析 之 3、爬取天气数据并用Pygal绘图
作者:互联网
3、爬取天气数据并用Pygal绘图
需求:
- 使用 Python 获取 2018 年太原的天气的最高气温和最低气温信息
- 使用 Pygal 展示天气数据
步骤:
-
下载、提取数据
- 使用 urllib.request 向 https://m.tianqi.com/ 发送请求,获取该网站的源代码
- 使用 re 模块来解析网站源代码,从中提取日期、天气最高气温、天气最低气温数据
-
数据清洗
- 检查数据丢失和数据格式错误情况
- 对数据异常情况,生成报告,略过发生错误的数据,继续处理
-
使用 Pygal 展示天气数据
- 创建、配置折线图
- 展示最高气温、最低气温
import urllib.request, re
import datetime, pygal
# 下载网页源码
def get_html(city, year, month):
url = 'https://m.tianqi.com/lishi/%s/%s%s.html' % (city, year, month)
request = urllib.request.Request(url)
request.add_header('User-Agent', 'Mozilla/5.0') # 设置User-Agent头,避免产生403错误
return urllib.request.urlopen(request).read().decode('UTF-8')
dates, lows, highs = [], [], [] # 日期、最高低气温、最高气温列表
city = 'taiyuan' # 地点
year = '2018' # 年
months = ['%02d' % i for i in range(1, 13)] # 月
prev_day = datetime.datetime(2017, 12, 31) # 开始日期,用于判断数据是否缺少天
# 1.下载、提取数据
for month in months:
html = get_html(city, year, month) # 下载网页源码
nospace_text = ''.join(html.split()) # 将网页源代码的空格去掉
pattern = re.compile('<divclass="weatherbox">(.*?)</div><divclass="clearline1">') # 全部天气数据的 div 元素对应的正则表达式
div_list = re.findall(pattern, nospace_text)
pattern1 = re.compile('<dlclass="table_day15">(.*?)</dl>') # 每日天气的 dl 元素对应的正则表达式
dls = re.findall(pattern1, div_list[0])
# 遍历 dls 获取每天的天气气温数据
for dl in dls:
date_pattern = re.compile('<ddclass="date">(.*?)</dd>') # 日期对应正则表达式
date_dd = re.findall(date_pattern, dl)
d_str = year + '/' + date_dd[0][0:5] # 生成日期格式字符串
temp_pattern = re.compile('<ddclass="txt2">(.*?)</dd>') # 气温数据对应的正则表达式
temp_dd = re.findall(temp_pattern, dl)
low_pattern = re.compile('^(.*?)~') # 最低气温数据对应的正则表达式
low_li = re.findall(low_pattern, temp_dd[0])
high_pattern = re.compile('<b>(.*?)</b>') # 最高气温数据对应的正则表达式
high_li = re.findall(high_pattern, temp_dd[0])
# 2.数据清洗(检查日期和温度数据)
try:
# 得到日期、最低气温、最高气温
cur_day = datetime.datetime.strptime(d_str, '%Y/%m/%d')
low = int(low_li[0])
high = int(high_li[0])
except ValueError:
print(cur_day, '温度数据格式有错')
else:
# 判断两个日期之间是否差一天,若差值不为一天,说明数据丢失
diff = cur_day - prev_day
if diff != datetime.timedelta(days = 1):
print('在%s之前丢失了%d天的数据' % (d_str, diff.days - 1))
dates.append(d_str)
lows.append(low)
highs.append(high)
prev_day = cur_day
# 3.使用 Pygal 展示天气数据
bar = pygal.Line() # 创建图(折线图)
bar.add('最低气温', lows)
bar.add('最高气温', highs)
bar.x_labels = dates
bar.x_labels_major = dates[::30] # 设置X轴的主刻度
bar.show_minor_x_labels = False # 设置不显示 X 轴小刻度(避免刻度标签拥挤)
bar.x_label_rotation = 45
bar.title = '太原%s年的气温分析' % year
bar.x_title = '日期'
bar.y_title = '气温(摄氏度)'
bar.legend_at_bottom = True
bar.show_x_guides = False
bar.show_y_guides = True
bar.render_to_file('temp.svg')
在2018/02/01之前丢失了1天的数据
在2018/04/01之前丢失了1天的数据
在2018/06/01之前丢失了1天的数据
在2018/08/01之前丢失了1天的数据
在2018/09/01之前丢失了1天的数据
在2018/11/01之前丢失了1天的数据
标签:bar,Python,pattern,爬取,re,2018,Pygal,气温,数据 来源: https://blog.csdn.net/qq_36512295/article/details/95762900