前言
Python爬虫爬取天气数据+可视化的简单实现
我贩卖日落,你像神明一样慷慨地将光洒向我,从此点亮了人间
数据来源
数据主要选取了中国天气网中南昌的天气数据进行爬取 由于改页面的数据通过JSON数据包的格式进行传输,首先找到了捕获页面加载的数据包 找到数据接口后接下来编写代码对气温数据进行爬取
爬虫代码
import csv
import time
import re
import os
import requests
import json
import numpy as np
import matplotlib.pyplot as plt
url='http://d1.weather.com.cn/calendar_new/2020/101240101_'
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36',
'Referer':'http://www.weather.com.cn/',
}
filedir='./json/'
field=['alins', 'als', 'blue', 'c1', 'c2', 'cla', 'date', 'des', 'fe', 'hgl', 'hmax', 'hmin', 'hol', 'insuit', 'jq', 'max', 'maxobs', 'min', 'minobs', 'nl', 'nlyf', 'r', 'rainobs', 'suit', 't1', 't1t', 't2', 't3', 't3t', 'time', 'today', 'update', 'w1', 'wd1', 'winter', 'wk', 'wor', 'ws1', 'yl']
def getJsonData(url,headers,month):
t=time.time()
date='2020'+'{:02}'.format(month)
suffix='.html?_='
rubbing=int(round(t * 1000))
url=url+date+suffix+str(rubbing)
response = requests.get(url, headers=headers)
response.encoding="utf-8"
json_code=response.text.replace('var fc40 = ','')
json_page = json.loads(json_code)
saveJsonData(json_page,date+'.csv')
def saveJsonData(json_page,filename):
if not os.path.exists(filedir):
os.makedirs(filedir)
with open(filedir+filename,'w',newline='') as f:
writer=csv.DictWriter(f,fieldnames=field)
writer.writeheader()
for inf in json_page:
if filename[:-4] in inf['date']:
writer.writerow(inf)
print(filename+'保存成功!')
for i in range(1,13):
getJsonData(url,headers,i)
print('成功获取南昌市2020年气温&降水数据!')
运行效果: 可以看到成功爬取了各月的气温数据
数据分析&可视化展示
import os
import csv
import numpy as np
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = 'SimHei'
plt.rcParams['axes.unicode_minus'] = False
filedir='./json/'
monthly_ave_high_temp=[]
monthly_ave_low_temp=[]
monthly_ave_temp=[]
monthly_ave_prec=[]
monthly_high_temp=[]
monthly_low_temp=[]
daily_temp=[]
daily_prec=[]
month_temp=[]
def ReadCSVFile(filedir):
for root,dirs,files in os.walk(filedir):
for filename in files:
with open(filedir+filename,'r') as f:
high_temp=[]
low_temp=[]
temp=[]
prec=[]
reader=csv.reader(f)
headers=next(reader)
for row in reader:
prec.append(int(row[9][:-1]))
high_temp.append(int(row[10]))
low_temp.append(int(row[11]))
temp.append((int(row[10])+int(row[11]))/2)
daily_temp.append((int(row[10])+int(row[11]))/2)
daily_prec.append(int(row[9][:-1]))
monthly_high_temp.append(high_temp)
monthly_low_temp.append(low_temp)
monthly_ave_high_temp.append(np.mean(high_temp))
monthly_ave_low_temp.append(np.mean(low_temp))
monthly_ave_temp.append((np.mean(high_temp)+np.mean(low_temp))/2)
monthly_ave_prec.append(np.mean(prec))
month_temp.append(temp)
print("获取JSON数据成功!")
ReadCSVFile(filedir)
plt.subplots(figsize=(30,20))
plt.xticks(range(0,13,1),rotation=30)
plt.yticks(range(0,38,1))
plt.grid()
x=np.arange(1, 13)
y1=monthly_ave_high_temp
y2=monthly_ave_temp
y3=monthly_ave_low_temp
y4=[np.mean(monthly_ave_temp)]*12
plt.plot(x,monthly_ave_high_temp,'*-',color='red',linewidth=0.8)
plt.plot(x,monthly_ave_temp,'o-',color='yellow',linewidth=0.8)
plt.plot(x,monthly_ave_low_temp,'o-',color='green',linewidth=0.8)
plt.plot(x,[np.mean(monthly_ave_temp)]*12,'--',color='red',linewidth=0.9)
plt.fill_between(x, monthly_ave_high_temp, monthly_ave_low_temp, facecolor='blue', alpha=0.2)
bar_width = 0.35
plt.plot(x,y1,label='月平均最高温',color='red')
plt.plot(x,y2,label='月平均温度',color='yellow')
plt.plot(x,y3,label='月平均最低温',color='green')
plt.plot(x,y1,label='年平均温度',color='red')
plt.legend(bbox_to_anchor=(1,1),
loc="upper right",
ncol=1,
mode="None",
borderaxespad=0,
title="图例",
shadow=False,
fancybox=True)
plt.title('2020年南昌市年平均气温变化情况',fontproperties='SimHei',fontsize=15)
plt.xlabel('月份',fontproperties='SimHei',fontsize=15)
plt.ylabel('温度/℃',fontproperties='SimHei',fontsize=15)
plt.savefig('2020年南昌市年平均气温变化情况',dpi=300)
plt.subplots(figsize=(30,20))
plt.xlim(0,32)
plt.subplots_adjust(wspace=0.35,hspace=0.55)
for i in range(1,13):
plt.subplot(3,4,i)
plt.plot(np.arange(1, len(monthly_high_temp[i-1])+1),monthly_high_temp[i-1],'*-',color='red',linewidth=0.8)
plt.plot(np.arange(1, len(monthly_low_temp[i-1])+1),monthly_low_temp[i-1],'*-',color='blue',linewidth=0.8)
ave_temp=(np.mean(monthly_low_temp[i-1])+np.mean(monthly_high_temp[i-1]))/2
plt.plot(np.arange(1, len(monthly_low_temp[i-1])+1),[ave_temp]*len(monthly_low_temp[i-1]),'-',color='green',linewidth=0.8)
plt.title('2020年南昌市'+str(i)+'月气温变化情况',fontproperties='SimHei',fontsize=15)
plt.xlabel('日期',fontproperties='SimHei',fontsize=15)
plt.ylabel('温度/℃',fontproperties='SimHei',fontsize=15)
plt.plot(np.arange(1, len(monthly_high_temp[i-1])+1),monthly_high_temp[i-1],label='每日最高温',color='red')
plt.plot(np.arange(1, len(monthly_high_temp[i-1])+1),monthly_low_temp[i-1],label='每日最低温',color='blue')
plt.plot(np.arange(1, len(monthly_high_temp[i-1])+1),[ave_temp]*len(monthly_low_temp[i-1]),label='当月平均温',color='green')
plt.legend(bbox_to_anchor=(1.6,2.5),
loc="upper right",
ncol=1,
mode="None",
borderaxespad=0,
title="图例",
shadow=False,
fancybox=True)
plt.savefig('2020年南昌市各月气温变化情况',dpi=300)
x_data=np.arange(1, 13)
y_data=monthly_ave_temp
for i in range(len(y_data)):
y_data[i]=round(y_data[i],2)
fig,ax = plt.subplots(figsize=(30,20))
plt.xlabel('月份',fontproperties='SimHei',fontsize=15)
plt.ylabel('月平均温度/℃',fontproperties='SimHei',fontsize=15)
ax.bar(x_data,y_data)
for x,y in zip(x_data,y_data):
ax.annotate(str(y)+'℃',(x,y+0.05),fontsize=14,horizontalalignment='center')
plt.title('2020年南昌市月平均气温变化情况',fontproperties='SimHei',fontsize=15)
plt.savefig('2020年南昌市月平均气温变化情况',dpi=300)
df=pd.Series(daily_temp)
size=[]
explode=(0.05,0.1,0.05,0.1,0.15,0.15,0.05)
labels=['[0,5)','[5,10)','[10,15)','[15,20)','[20,25)','[25,30)','[30,35)']
elements=['温度处于[0,5)℃','温度处于[5,10)℃','温度处于[10,15)℃','温度处于[15,20)℃','温度处于[20,25)℃','温度处于[25,30)℃','温度处于[30,35)℃']
for i in range(0,7):
size.append(df[(df>=i*5) & (df<(i*5+5))].count())
plt.subplots(figsize=(15,10))
wedges,texts,autotexts=plt.pie(size,explode,labels=elements,autopct='%1.1f%%',startangle=90,radius=0.8)
plt.axis()
plt.legend(wedges,
elements,
fontsize=12,
title="说明",
loc="upper right",
bbox_to_anchor=(0.91, 0, 0.3, 1))
plt.title('2020年南昌市每日气温统计情况',fontproperties='SimHei',fontsize=15)
plt.savefig('2020年南昌市每日气温统计情况',dpi=300)
plt.subplots(figsize=(15,10))
data1=pd.read_csv('./2020.csv',encoding='utf-8')
plt.title('2020年南昌市最高气温分布概率',fontproperties='SimHei',fontsize=15)
sns.distplot(data1['hmax'])
plt.xlabel('温度/℃',fontproperties='SimHei',fontsize=15)
plt.ylabel('概率',fontproperties='SimHei',fontsize=15)
plt.savefig('2020年南昌市最高气温分布概率',dpi=300)
data1=pd.read_csv('./2020.csv',encoding='utf-8')
sns.lmplot('date','hmax',data1,hue='月份',fit_reg=False,markers='*')
plt.title('2020年南昌市全年气温分布图散点图',fontproperties='SimHei',fontsize=13, y=-0.11)
plt.xlabel('日期',fontproperties='SimHei',fontsize=15)
plt.ylabel('温度/℃',fontproperties='SimHei',fontsize=15)
plt.savefig('2020年南昌市全年气温分布图散点图',dpi=300)
plt.show()
代码中运用了主要运用了numpy和pandas对数据进行了处理和分析,同时也利用了matplotlib.pyplot和seaborn对图像进行处理,进行数据展示 可视化展示结果
后记
代码中以给出详细的注释,若还有疑问欢迎留言评论
|