一.设计方案
爬虫名称:爬取天气情况并进行可视化
爬虫内容:爬取2020年3月份莆田市天气情况
爬虫设计:目标url,获取网页源代码,数据提取,数据保存
二.页面的结构特征分析(网址:http://www.tianqihoubao.com/lishi/putian/month/202003.html)
结构特质分析:源文件为html结构
页面解析以及节点查找
找到节点为<table width="100%" class="b" border="0" cellspacing="1" cellpadding="1">
三.爬虫程序
数据爬取与采集
import requests from bs4 import BeautifulSoup #目标url url = 'http://www.tianqihoubao.com/lishi/putian/month/202003.html' #获取网页源代码 resp = requests.get(url) html = resp.content.decode('gbk') #数据提取 soup = BeautifulSoup(html,'html.parser') tr_list = soup.find_all('tr') print(tr_list)
结果如图(部分截取)
数据处理
dates,conditions,temp = [],[],[] for data in tr_list[1:]: sub_data = data.text.split() dates.append(sub_data[0]) conditions.append(''.join(sub_data[1:3])) temp.append(''.join(sub_data[3:6])) _data = pd.DataFrame() _data['日期'] = dates _data['天气情况'] = conditions _data['气温'] = temp print(_data)
结果如图
数据可视化
#数据可视化 from matplotlib import pyplot as plt #显示中文 plt.rcParams['font.sans-serif'] = ['SimHei'] #显示负号 plt.rcParams['axes.unicode_minus'] = False data = pd.read_csv('putian.csv') #数据处理 data['最高气温'] = data['气温'].str.split('/',expand=True)[0] data['最低气温'] = data['气温'].str.split('/',expand=True)[1] data['最高气温'] = data['最高气温'].map(lambda x:int(x.replace('℃',''))) data['最低气温'] = data['最低气温'].map(lambda x:int(x.replace('℃',''))) dates = data['日期'] highs = data['最高气温'] lows = data['最低气温'] #画图 fig = plt.figure(dpi=128,figsize=(10,6)) plt.plot(dates,highs, c='red',alpha=0.5) plt.plot(dates,lows, c='blue',alpha=0.5) plt.fill_between(dates,highs,lows,facecolor='blue',alpha=0.2) #图表格式 #设置图形格式 plt.title('2020年三月份天气',fontsize=24) plt.xlabel('',fontsize=6) fig.autofmt_xdate() #绘制斜的日期标签,避免重叠 plt.ylabel('气温',fontsize=12) plt.tick_params(axis='both',which='major',labelsize=10) #修改刻度 plt.xticks(dates[::1]) #显示折线图 plt.show()
结果如图
最高气温与最低气温的相关系数及两者的散点图与回归方程
相关系数
#绘制散点图以及回归方程 #计算相关系数 X = highs Y = lows X.corr(Y)
结果如图
散点图
#散点图 plt.title('2020年三月份最高温与最低温散点图',fontsize=20) x = highs y = lows plt.xlabel('最高温度',fontsize=12) plt.ylabel('最低温度',fontsize=12) plt.scatter(x,y,color='purple',linewidth=2) plt.show()
结果如图
回归方程
#回归方程 import numpy as np from scipy.optimize import leastsq X = np.array(highs) Y = np.array(lows) def func(params, x): k, b = params return k*x+b def error(params,x,y): return func(params,x) - y def main(): plt.figure(figsize=(10,6)) p0 = [0,0] Para = leastsq(error, p0, args=(X,Y)) k, b = Para[0] print("k={:.2f},b={:.2f}".format(k,b)) plt.scatter(X,Y,color='green',label='样本数据',linewidth=2) #画拟合曲线 x = np.linspace(1,30,30) y = k*x+b plt.plot(x,y,color='red',label='拟合曲线',linewidth=2) plt.title('2020年三月分最低温与最高温光系图') plt.grid() plt.legend() plt.show() main()
结果如图
数据持久化
fig = plt.gcf() plt.show() fig.savefig('putian.png', dpi=100)
结果如图
整理后的完整代码
1 import requests 2 import pandas as pd 3 from bs4 import BeautifulSoup 4 #目标url 5 url = 'http://www.tianqihoubao.com/lishi/putian/month/202003.html' 6 #获取网页源代码 7 resp = requests.get(url) 8 html = resp.content.decode('gbk') 9 #数据提取 10 soup = BeautifulSoup(html,'html.parser') 11 tr_list = soup.find_all('tr') 12 13 dates,conditions,temp = [],[],[] 14 for data in tr_list[1:]: 15 sub_data = data.text.split() 16 dates.append(sub_data[0]) 17 conditions.append(''.join(sub_data[1:3])) 18 temp.append(''.join(sub_data[3:6])) 19 _data = pd.DataFrame() 20 _data['日期'] = dates 21 _data['天气情况'] = conditions 22 _data['气温'] = temp 23 _data.to_csv('putian.csv',index=False,encoding='utf-8')#去掉索引以及避免乱码 24 25 #数据可视化 26 from matplotlib import pyplot as plt 27 #显示中文 28 plt.rcParams['font.sans-serif'] = ['SimHei'] 29 #显示负号 30 plt.rcParams['axes.unicode_minus'] = False 31 data = pd.read_csv('putian.csv') 32 #数据处理 33 data['最高气温'] = data['气温'].str.split('/',expand=True)[0] 34 data['最低气温'] = data['气温'].str.split('/',expand=True)[1] 35 data['最高气温'] = data['最高气温'].map(lambda x:int(x.replace('℃',''))) 36 data['最低气温'] = data['最低气温'].map(lambda x:int(x.replace('℃',''))) 37 38 dates = data['日期'] 39 highs = data['最高气温'] 40 lows = data['最低气温'] 41 42 #画图 43 fig = plt.figure(dpi=128,figsize=(10,6)) 44 45 plt.plot(dates,highs, c='red',alpha=0.5) 46 plt.plot(dates,lows, c='blue',alpha=0.5) 47 48 plt.fill_between(dates,highs,lows,facecolor='blue',alpha=0.2) 49 50 #图表格式 51 #设置图形格式 52 plt.title('2020年三月份天气',fontsize=24) 53 plt.xlabel('',fontsize=6) 54 fig.autofmt_xdate() #绘制斜的日期标签,避免重叠 55 plt.ylabel('气温',fontsize=12) 56 plt.tick_params(axis='both',which='major',labelsize=10) 57 58 #修改刻度 59 plt.xticks(dates[::1]) 60 61 #显示折线图 62 plt.show() 63 64 #绘制散点图以及回归方程 65 #计算相关系数 66 x = highs 67 y = lows 68 x.corr(y) 69 70 #散点图 71 plt.title('2020年三月份最高温与最低温散点图',fontsize=20) 72 x = highs 73 y = lows 74 plt.xlabel('最高温度',fontsize=12) 75 plt.ylabel('最低温度',fontsize=12) 76 plt.scatter(x,y,color='purple',linewidth=2) 77 plt.show() 78 79 #回归方程 80 import numpy as np 81 from scipy.optimize import leastsq 82 X = np.array(highs) 83 Y = np.array(lows) 84 def func(params, x): 85 k, b = params 86 return k*x+b 87 def error(params,x,y): 88 return func(params,x) - y 89 def main(): 90 plt.figure(figsize=(10,6)) 91 p0 = [0,0] 92 Para = leastsq(error, p0, args=(X,Y)) 93 k, b = Para[0] 94 print("k={:.2f},b={:.2f}".format(k,b)) 95 plt.scatter(X,Y,color='green',label='样本数据',linewidth=2) 96 #画拟合曲线 97 x = np.linspace(1,30,30) 98 y = k*x+b 99 plt.plot(x,y,color='red',label='拟合曲线',linewidth=2) 100 plt.title('2020年三月分最低温与最高温光系图') 101 plt.grid() 102 plt.legend() 103 plt.show() 104 main() 105 106 #数据持久化 107 fig = plt.gcf() 108 plt.show() 109 fig.savefig('putian.png', dpi=100)
完整运行结果如图
四.结论
1.2020年3月份莆田每日温差较大,且呈现出逐渐上升趋势,每日最高温度与最低温度相关性也较大,且进行数据可视化后可以更为直观明了的观察,而三月份最低温度也在10摄氏度左右,可以看出是一个很适合居住的城市。
2.本次程序设计任务,我选择的是爬取天气后报网,课题是爬取3月份的天气情况,并不是天气预报,对于这个网址的爬取相对简单,首先它是一个静态网页,其次节点也相当好找,而且爬虫部分也不需要伪装,可以说是一个相对简单的课题。但是不可否认的是,在程序设计过程中出现了较多问题,如基础不扎实,一部分报错无法看懂,在数据处理时将列表改为整形数据时遇到了困难,进行了大量尝试才最终成功,又如在数据可视化过程中遇到了纵坐标数据出现乱序,而找不出原因,又进行了大量的尝试,再如最后阶段的数据持久化,初看认为很简单,却也让我大费脑筋,更让我认识的自己的基本功之不扎实,但相较于上一次作业而言,完成度相对较高,基本完成了任务目标。
以上。