前言
上一篇文章主要講了如何解析網頁,本篇文章主要來寫一下如何發起請求。可能看過前兩篇文章的人就開始疑惑了,請求?你不是說一行代碼就可以搞定了么。的確,一行代碼就能搞定。但是請求部分既然扮演着瀏覽器的角色,我們是不是應該盡量讓它變得和瀏覽器一樣。而我在第一篇文章中也講到,爬蟲是模擬人的行為去獲取數據。那么我們就需要知道,一個人去訪問網站有什么樣的行為?爬蟲怎么去模擬人的行為?
請求頭
當一個人打開瀏覽器輸入網址敲下回車,會發起一個HTTP請求,即Request,來訪問網站服務端,服務端接收請求並返回響應內容,即Response。在發起請求時,Request會有一個請求頭,即Headers,來描述請求信息,例如Content-type、User-Agent、cookie等。相對的也會有一個響應頭,這里不多關注。
User-Agent
在爬蟲程序的開發中,請求頭中必須添加的就是User-Agent。UA記錄了瀏覽器、操作系統、版本等信息,很多網站會通過檢測UA來判斷是否是爬蟲程序發起的請求。
Chrome瀏覽器請求頭信息:
爬蟲程序請求頭信息:
從上圖可以看出,Python爬蟲的UA默認的python-requests,所以我們要修改爬蟲程序的UA。
我們通過headers參數在請求頭添加UA,這樣默認的UA就會被修改。
cookie
至於其他屬性,比較關注的就是cookie。在web開發中,服務端在用戶第一次訪問時生成cookie,並通過響應頭中的Set-Cookie屬性,返回瀏覽器並被持久化。在cookie的有效期內訪問服務端,瀏覽器都會在請求頭中帶着cookie,以此來表明自己的身份。
這里以百度網盤為例來說明。
這時我還沒有登錄百度網盤,同時清理了瀏覽器中所有關於百度網盤的cookie。第一次訪問分享鏈接時,服務端通過響應頭會返回一個cookie給瀏覽器。
當我刷新頁面再次請求時,請求頭中就有了之前cookie屬性。
到這里,cookie的來源和基本用法其實就講完了。為了更好的去讓大家了解一下cookie,我又多寫了一部分。
此時訪問任何有提取碼的分享鏈接,仍然都需要輸入提取碼,因為我們沒有登陸百度網盤,目前的cookie不足以向百度網盤表明我的用戶信息。但是,如果我們在登錄了百度雲盤賬號的瀏覽器中,訪問自己的分享鏈接則不需要輸入提取碼,就是下面這種情況。
再次強調,是訪問自己賬號分享的資源鏈接不需要輸入提取碼。
我登錄了自己百度雲盤后,開始訪問自己的分享鏈接,沒有輸入提取碼就直接訪問到了資源,這是為啥?這就是cookie的力量!!。
登錄百度網盤:
假設這是第一次登錄百度雲盤,百度雲盤生成了cookie返回給瀏覽器,這里我們只關注PANPAS這個字段的變化。
我們看一下此刻瀏覽器存儲的cookie值:
瀏覽器存儲的cookie和第一次登錄百度雲盤返回的cookie是一樣的。
這時我們刷新頁面再次訪問:
我們發現請求頭中攜帶了剛剛瀏覽器存儲的cookie,但是響應頭中又返回了一個新的cookie,我們再看一下瀏覽器中此刻存儲的cookie:
此刻,瀏覽器中存儲的cookie已經變成了最新的。從這里就能看出每次訪問百度網盤,服務端都會新建一個cookie返回給瀏覽器,覆蓋之前的cookie。但是大部分網站都是在用戶第一次請求或者cookie過期時才會新建cookie,這里就不需要過多糾結。我們只需要知道:cookie代表了用戶信息即可。
上面主要就是一些cookie的簡單理論,現在我們從代碼中來看cookie如何應用。
首先我們不加cookie來訪問我的百度雲盤分享鏈接:
我們從網頁內容可以看出,進入的是輸入提取碼的頁面。
這時,我們將登錄了百度網盤的瀏覽器中的cookie復制過來,放在請求頭中再次執行。
如圖,請求頭在攜帶了cookie之后訪問我自己的分享鏈接,就直接訪問到了資源頁面,而不再是輸入提取碼頁面。
大概流程再整一下:爬蟲程序帶着cookie去訪問分享鏈接,百度雲盤一看這個cookie代表的人和資源分享人居然是同一個人,那就不需要再重定向到輸入提取碼頁面了,直接訪問資源就可以了。
referer
referer代表的是從哪個url跳轉到此頁面的,通常用來判斷此次請求是否是從網站內點擊觸發的。例如我從騰訊視頻的動漫頻道點進去斗羅大陸播放頁,則跳轉到斗羅大陸頁面請求的referer就是動漫頻道的url。
如圖,/channle/cartoon代表的就是動漫頻道。
這個屬性平時不怎么用。到目前為止,我就只在一次爬蟲程序開發中,遇到過這個問題,網站通過檢測referer來判定你是否是直接訪問的這個url,后來我就將網站首頁的url填到了每個請求頭referer中。
用法可以看UA那個程序截圖。
請求頻率
眾所周知,程序的運行速度是非常快的。假如我們爬取一個網站,這個網站有1w個頁面,我們在代碼中循環請求1w次,啟動程序,或許幾秒鍾就搞定了,但是你認為一個人會有這么快的請求頻率么。所以我們需要限制請求間隔,方法很簡單。
Java
Thread.sleep(millis)
Python
time.sleep(secs)
Scrapy爬蟲框架
# settings中,0.3代表0.3s
DOWNLOAD_DELAY = 0.3
代理IP
很多網站識別爬蟲程序的基本手段就是通過請求頻率來判斷,即記錄一個IP在一段時間內請求了多少次。所以如果我們有足夠的代理IP,就可以提高請求頻率。
通常獲取代理IP的方法有付費購買和從免費代理IP網站獲取,之前的西刺代理就是專門提供免費代理IP的網站,但免費代理IP的存活率通常不高。很多人就開始專門設計程序來構建代理IP池,獲取了免費代理IP之后,通過程序反復驗證代理IP的存活性。這里主要先說明爬蟲程序中入門如何添加代理IP。
這里我找了一個代理IP,添加在了代碼中。
import requests
url = 'https://ipinfo.io'
proxies = {
'https': 'https://183.220.xxx.xx:80'
}
response = requests.get(url, proxies=proxies)
print(response.text)
對IP識別網站發起請求並輸出結果。
爬蟲程序的IP已經不再是爬蟲運行主機IP,而變成了代理IP。至於代理池的構建,可能以后我會寫一下。
結語
本篇文章從請求頭、請求頻率、代理IP三個方面,講述了爬蟲如何去模擬人的行為,這是爬蟲程序開發最基本的常識,也是最常見的應對反爬蟲的方法。有時候,一個爬蟲程序的好壞,並不是取決爬蟲程序的性能,而是取決於網站是否能識別出這是個爬蟲程序。
知道了這些,是否就可以肆無忌憚的去爬取數據了呢?其實是不可以的,我們爬取數據一定要在合理合法的范圍內,亦不可逾越法律底線。所以下篇文章主要講一下自己對數據爬取規范的一些理解。期待下一次相遇。
寫的都是日常工作中的親身實踐,處於自己的角度從0寫到1,保證能夠真正讓大家看懂。
文章會在公眾號 [入門到放棄之路] 首發,期待你的關注。