天气数据爬取及分析
气象数据爬取与分析
前言
通过爬取2020年长治市的气温和天气状况来简要分析。
数据来源地址:http://lishi.tianqi.com/changzhi
而每月的数据,以2020年1月为例,链接为:http://lishi.tianqi.com/changzhi/202001.html
数据爬取
采用Requests,BeautifulSoup两个工具。遍历12个月份的链接,为了防止被屏蔽,每次请求前暂停3秒。
谁知,网站可能有个简单的反爬机制,通过伪造一个数据包的user-agent信息,伪装成浏览器请求成功。
爬取后,保存在json格式的文件,如下为文件中部分数据截图
简要分析
每一条数据如下格式:['2020-01-01 星期三 ', '5℃', '-7℃', '晴转多云', '南风 1级']
求取每月的最高气温与最低气温的平均值,得出全年气温变化,如下所示,由此可见昼夜温差并不是很大,且全年气温较为适宜,四季分明。
统计全年的天气状况,并绘制饼图,如下所示,由于一些天气状况较少,所以只展示前八的天气,由下可见,全年晴天较多(带来好心情),降水较少,较为干旱。
统计数据:{'晴': 146, '多云': 87, '阴': 51, '晴转多云': 39, '多云转阴': 8, '小雨': 7, '阴转多云': 4, '小雨到中雨': 4, '多云转雪': 2, '霾转雪': 2, '霾': 2, '阴转雪': 2, '小雪': 2, '雪': 1, '霾转多云': 1, '霾转晴': 1, '小雨转雨': 1, '多云转雨': 1, '小雨转多云': 1, '中雨到大雨': 1, '多云转多云': 1, '阴转雨': 1, '阴到小雨': 1}
饼图:
代码
import re
import requests
from bs4 import BeautifulSoup
import time
from tqdm import tqdm
import json
import collections
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif']=['SimHei']
#共有12个月需要爬取,设置url链接中page的参数,其中tqdm用于进度条
year=[]
for i in tqdm(range(1,13)):
time.sleep(3)
url = 'http://lishi.tianqi.com/changzhi/2020'+str('%02d'%i)+'.html'
# 请求页面
headers={'User-Agent':'Mozilla / 5.0(Windows NT 10.0;Win64;x64) AppleWebKit / 537.36(KHTML, likeGecko) Chrome / 95.0.4638.69Safari / 537.36'}
r = requests.get(url,headers=headers)
r.encoding = r.apparent_encoding
html = BeautifulSoup(r.text, 'html.parser')
table=html.find_all('ul',{'class':'thrui'})
li=table[0].find_all('li')
month=[]
for i in li:
div=i.find_all('div')
day=[]
for j in div:
day.append(j.get_text())
month.append(day)
year.append(month)
with open('C:/Users/DELL/Desktop/season.json', 'w', encoding='utf-8') as f:
json.dump(year,f)
with open('C:/Users/DELL/Desktop/season.json', 'r', encoding='utf-8') as f:
year=json.load(f)
print(year)
year_high_temperature=[]
year_low_temperature = []
year_weather=[]
for month in year:
high_temperature=0
low_temperature = 0
month_weather=[]
for day in month:
high_day_temperature=int(re.findall(r'-?\d+',day[1])[0])
low_day_temperature = int(re.findall(r'-?\d+', day[2])[0])
high_temperature=high_temperature+high_day_temperature
low_temperature = low_temperature+low_day_temperature
month_weather.append(day[3])
year_high_temperature.append(round(high_temperature / len(month)))
year_low_temperature.append(round(low_temperature / len(month)))
year_weather.extend(month_weather)
plt.title(u'长治市全年每月最高温与最低温变化')
plt.xlabel(u'年份')
plt.ylabel(u'温度')
plt.plot(range(1,13),year_high_temperature,'-o',label=u'最高温')
plt.plot(range(1,13),year_low_temperature,'-o',label=u'最低温')
plt.legend(loc = 'upper right')
plt.show()
year_weather=collections.Counter(year_weather)
print(year_weather)
weather=[]
days=[]
for key,value in year_weather.most_common(8):
weather.append(key)
days.append(value)
print(days)
plt.title(u'长治市全年天气状况饼状图')
plt.pie(days,labels=weather,autopct='%1.1f%%',shadow=False)
plt.show()