爬蟲對象選擇
打開中國天氣網站,例如我要爬取廈門近 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')
爬取的數據如下所示: