爬蟲入門到放棄系列03:爬蟲如何模擬人的瀏覽行為

前言

上一篇文章主要講了如何解析網頁,本篇文章主要來寫一下如何發起請求。可能看過前兩篇文章的人就開始疑惑了,請求?你不是說一行代碼就可以搞定了么。的確,一行代碼就能搞定。但是請求部分既然扮演着瀏覽器的角色,我們是不是應該盡量讓它變得和瀏覽器一樣。而我在第一篇文章中也講到,爬蟲是模擬人的行為去獲取數據。那麼我們就需要知道,一個人去訪問網站有什麼樣的行為?爬蟲怎麼去模擬人的行為?

請求頭

當一個人打開瀏覽器輸入網址敲下回車,會發起一個HTTP請求,即Request,來訪問網站服務端,服務端接收請求並返迴響應內容,即Response。在發起請求時,Request會有一個請求頭,即Headers,來描述請求信息,例如Content-type、User-Agent、cookie等。相對的也會有一個響應頭,這裡不多關注。

User-Agent

在爬蟲程序的開發中,請求頭中必須添加的就是User-Agent。UA記錄了瀏覽器、操作系統、版本等信息,很多網站會通過檢測UA來判斷是否是爬蟲程序發起的請求。

Chrome瀏覽器請求頭信息:

Chrome Request Headers

爬蟲程序請求頭信息:

Python Request Headers

從上圖可以看出,Python爬蟲的UA默認的python-requests,所以我們要修改爬蟲程序的UA。

修改請求頭

我們通過headers參數在請求頭添加UA,這樣默認的UA就會被修改。

至於其他屬性,比較關注的就是cookie。在web開發中,服務端在用戶第一次訪問時生成cookie,並通過響應頭中的Set-Cookie屬性,返回瀏覽器並被持久化。在cookie的有效期內訪問服務端,瀏覽器都會在請求頭中帶着cookie,以此來表明自己的身份。

這裡以百度網盤為例來說明。

這時我還沒有登錄百度網盤,同時清理了瀏覽器中所有關於百度網盤的cookie。第一次訪問分享鏈接時,服務端通過響應頭會返回一個cookie給瀏覽器。

Set-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

這個屬性平時不怎麼用。到目前為止,我就只在一次爬蟲程序開發中,遇到過這個問題,網站通過檢測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 = '//ipinfo.io'
proxies = {
    'https': '//183.220.xxx.xx:80'
}
response = requests.get(url, proxies=proxies)
print(response.text)

對IP識別網站發起請求並輸出結果。

代理IP驗證

爬蟲程序的IP已經不再是爬蟲運行主機IP,而變成了代理IP。至於代理池的構建,可能以後我會寫一下。

結語

本篇文章從請求頭、請求頻率、代理IP三個方面,講述了爬蟲如何去模擬人的行為,這是爬蟲程序開發最基本的常識,也是最常見的應對反爬蟲的方法。有時候,一個爬蟲程序的好壞,並不是取決爬蟲程序的性能,而是取決於網站是否能識別出這是個爬蟲程序。

知道了這些,是否就可以肆無忌憚的去爬取數據了呢?其實是不可以的,我們爬取數據一定要在合理合法的範圍內,亦不可逾越法律底線。所以下篇文章主要講一下自己對數據爬取規範的一些理解。期待下一次相遇。


寫的都是日常工作中的親身實踐,處於自己的角度從0寫到1,保證能夠真正讓大家看懂。

文章會在公眾號 [入門到放棄之路] 首發,期待你的關注。

公眾號