Python:40天天氣預報排名爬蟲
爬蟲物件選擇
開啟中國天氣網站,例如我要爬取廈門近 40 天的天氣情況,開啟對應的網頁。“weather40d”目錄是近 40 天的天氣,“101230201”是廈門城市的 id。
http://www.weather.com.cn/weather40d/101230201.shtml
開啟開發者工具,觀察到每一天的天氣資料還是比較複雜的,所以我們還是要找 API。
在 network 中觀察,Fetch/XHG 中沒有任何請求的互動,說明這個網頁要麼是靜態的,要麼是用 JavaScript 動態生成的。
隨便找一個在頁面中的字串,例如以 11 月 7 號的天氣“多雲轉小雨”為例,可以看到搜尋出一個結果。
檢視這個 JavaScript 檔案,可以看到這裡羅列了一系列的資料。
開啟詳細的資料,發現這個字典裡面的資料可以和網頁的資料對應,說明這個就是我們想要的 js 檔案。
請求頭修改
檢視這個請求的請求頭,得到這個 js 檔案的 url。
但是訪問這個 url,發現回顯 403 錯誤。403 錯誤表示資源不可用,也就是伺服器理解客戶的請求,但拒絕處理它,通常由於伺服器上檔案或目錄的許可權設定導致的。
也就是說只有特定的地方發起請求才能獲取這個資源,檢視請求頭,發現 “Referer” 欄位的值為中國天氣網站。Referer 欄位用於告訴伺服器該網頁是從哪個頁面連結過來的,因此很有可能我們想要的 js 檔案只接受來源於該網站的請求。
同時還有一個“User-Agent”欄位也需要設定,User-Agent 欄位會告訴網站伺服器訪問者是通過什麼工具來請求的。如果使用的是爬蟲,這個欄位會被顯式的註明是 Python 爬蟲,所以我們要改成瀏覽器。使用 requests 庫的 get 方法,同時夾帶標頭檔案進行請求就可以成功。
import requests url = "http://d1.weather.com.cn/calendar_new/2021/101230201_202111.html" headers = { "Referer":"http://www.weather.com.cn/", "User-Agent":"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.81 Safari/537.36" } r = requests.get(url=url, headers=headers) print("請求的狀態是:" + str(r.status_code))
資料處理
觀察 Response 的內容,發現除了開頭的 “var fc40 = [”這一串字串,後面的內容都是以 json 的格式存在的。所以只需要把一開始的 “var fc40 = [”刪掉,請求的內容就可以以 JSON 的格式解析。
首先修改編碼,然後剔除掉開頭的 11 個字元,用 json 庫就可以來解析這些資料。會得到一個存有當前頁面所有日期的天氣資料的 list,每個元素都是一個字典。
import json
content = r.content.decode(encoding='utf-8')
weathers = json.loads(content[11:])
最後就是獲取我們需要的資料了,我挑選的資料如下:
欄位 | 含義 |
---|---|
date | 日期 |
nlyf | 農曆月份 |
nl | 農曆日期 |
w1 | 天氣 |
wd1 | 風向 |
max | 最高溫度 |
min | 最低溫度 |
jq | 節氣 |
t1 | 溫度變化 |
hmax | 歷史最高溫均值 |
hmin | 歷史最低溫均值 |
hgl | 歷史降雨率 |
alins | 黃曆宜 |
als | 黃曆忌 |
將這些資料寫入 xls 檔案,程式碼如下:
import xlwt
writebook = xlwt.Workbook()
sheet = writebook.add_sheet('Sheet1')
keys = ['date','nlyf','nl','w1','wd1','max','min','jq','t1','hmax','hmin','hgl','alins','als']
for i in range(len(keys)):
sheet.write(0, i, keys[i])
for i in range(len(weathers)):
for j in range(len(keys)):
sheet.write(i + 1, j, weathers[i][keys[j]])
writebook.save('weathers.xls')
完整程式碼
爬取廈門地區近 40 天天氣預報資料,一個簡單的爬蟲 demo 如下:
import requests
import json
import xlwt
url = "http://d1.weather.com.cn/calendar_new/2021/101230201_202111.html"
headers = {
"Referer":"http://www.weather.com.cn/",
"User-Agent":"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.81 Safari/537.36"
}
r = requests.get(url=url, headers=headers)
if r.status_code == 200:
content = r.content.decode(encoding='utf-8')
weathers = json.loads(content[11:])
writebook = xlwt.Workbook()
sheet = writebook.add_sheet('Sheet1')
keys = ['date','nlyf','nl','w1','wd1','max','min','jq','t1','hmax','hmin','hgl','alins','als']
for i in range(len(keys)):
sheet.write(0, i, keys[i])
for i in range(len(weathers)):
for j in range(len(keys)):
sheet.write(i + 1, j, weathers[i][keys[j]])
writebook.save('weathers.xls')
爬取的資料如下所示: