一.設計方案
爬蟲名稱:爬取天氣情況並進行可視化
爬蟲內容:爬取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月份的天氣情況,並不是天氣預報,對於這個網址的爬取相對簡單,首先它是一個靜態網頁,其次節點也相當好找,而且爬蟲部分也不需要偽裝,可以說是一個相對簡單的課題。但是不可否認的是,在程序設計過程中出現了較多問題,如基礎不扎實,一部分報錯無法看懂,在數據處理時將列表改為整形數據時遇到了困難,進行了大量嘗試才最終成功,又如在數據可視化過程中遇到了縱坐標數據出現亂序,而找不出原因,又進行了大量的嘗試,再如最后階段的數據持久化,初看認為很簡單,卻也讓我大費腦筋,更讓我認識的自己的基本功之不扎實,但相較於上一次作業而言,完成度相對較高,基本完成了任務目標。
以上。
