爬蟲的矛與盾
一、基礎反爬手段:通過header內的欄位反爬
最基礎的反爬手段是通過請求的header內的欄位來判斷是否為爬蟲訪問:
1、通過user-agent欄位來判斷是否為瀏覽器訪問,爬蟲的破解措施為設置user-agent欄位為常用瀏覽器,來模擬瀏覽器訪問
2、通過referer欄位來判斷是從哪一個url跳轉到當前頁面,爬蟲通常該欄位設置為主頁即可
補充知識點:
標頭 (header) 是伺服器以HTTP協議傳HTML資料到瀏覽器前所送出的字串,在標頭與 HTML 文件之間尚需空一行分隔。
HTTP Referer是header的一部分,當瀏覽器向web伺服器發送請求的時候,一般會帶上Referer,告訴伺服器我是從哪個頁面鏈接過來的,伺服器基此可以獲得一些信息用於處理
User Agent中文名為用戶代理,簡稱 UA,它是一個特殊字元串頭,使得伺服器能夠識別客戶使用的操作系統及版本、CPU 類型、瀏覽器及版本、瀏覽器渲染引擎、瀏覽器語言、瀏覽器插件等
如何查看一個瀏覽器的版本?
查看瀏覽器的「幫助」--->「關於」
一般情況下,使用編程語言提供的第三方網路庫來發送HTTP請求會有一個默認的U-A,比如requests庫的默認U-A為"python-requests/2.8.1"(後面
二、通過訪問頻度反爬
這種反爬機制的原理是,真人通過瀏覽器訪問網站的速度(相對程序來講)是很慢的,所以如果某個IP在較短時間內發送了較多請求(具體閾值需要具體考慮)伺服器則認為請求來自爬蟲,比如58同城網站,通過驗證碼頁面降低真人訪問速度,以區分是否為爬蟲訪問,一般來講我們有兩種情況解決:
- 不斷更換虛擬IP地址
- 識別驗證碼
伺服器認為我們當前的出口IP訪問頻率過快,那麼我們換一個全新的IP不就好了嗎,當新的IP再此被認為訪問過快,我們就再重新換一個新的IP,如此往複。如何實現更換IP呢?其實我們不需要真正更換IP,而是通過一個代理IP轉發我們的請求。不少網站提供或羅列了一大批代理IP,我們可以抓取下來之後存儲起來,以備不時之需。不過,很多代理IP的壽命都比較短,所以最好有一套完整的機制來校驗已有代理IP的有效性。使用requests庫來更換代理IP的示例代碼如下:
request = requests.Session()request.proxies = {"http": "http://10.10.1.10:3128",}
除去更換代理IP,識別驗證碼也是一種可行的解決方案。不過,識別驗證碼的技術難度要比更換代理IP高個三四層樓。就像你剛才刷出58的驗證碼時,當你正確輸入驗證碼之後,就可以繼續正常訪問了。同樣地,當你的OCR程序識別出驗證碼中的文本之後,按照瀏覽器的請求方式向伺服器發送識別結果之後,一般就可以繼續正常訪問了。
面對這樣的網站,一種較好的的方式是用一台機器從慢到快測試被封的閥值,然後將程序按照比閥值低一點的速度抓取,如果量比較大,還可以將爬蟲並行化。
三、通過驗證碼限制
這樣的方式與上面的方式相比更加難處理的是,不管你的訪問頻次怎麼樣,你都需要輸入驗證碼才行。比如12306,不管你是登錄還是購票,也不論你是第一次還是第一萬次購買,你都需要輸入一個驗證碼之後才能繼續。這時候,在絕大部分情況下,你必須要想辦法識別驗證碼了。之所以說是大多數情況下,是因為在極少數極少數情況下(尤其是政府網站),棒槌程序員通過客戶端的JavaScript來校驗驗證碼,這時候對你的爬蟲來講,其實是沒有驗證碼的(比如中國商標網)。除開你遇到這種幾乎可以忽略不計的棒槌開發的網站,其他時候你只有通過識別驗證碼來繼續後面的操作了。
四、通過經常變換網頁結構
常見於一些社交網站,他們會經常更換網頁的結構,如果你是通過依賴網頁結構來解析需要的數據(不幸的是大部分情況下我們都需要通過網頁結構來解析需要的數據),則在原本的網頁位置找不到原本需要的內容。這時候,要分不同情況具體處理了。如果你只打算一次性抓取特定數據,那麼趕快行動,它以後結構變了無所謂,反正你也不打算在抓它一次。如果是需要持續性抓取的網站,就要仔細思考下應對方案了。一個簡單粗暴但是比較費力的辦法是,寫一個校驗腳本,定期校驗網頁結構,如果與預期不符,那麼趕快通知自己(或者特定開發者)修改解析部分,以應對網頁結構變化。
除此之外,可以考慮解析數據時通過數據的特點來解析而不是通過網頁結構,這樣只要網頁上我們需要的數據不變,基本可以不關心網頁結構如何。當然,這樣的方法也有弊端,那就是可能不能覆蓋百分之百的情況,在少數情況下,可能無法解析出我們需要的東西。比如我曾經寫過程序根據文本密度解析新聞正文,在絕大部分情況下可以正常抽取新聞正文,不過少數情況下,會出現解析失敗的情況。
五、通過賬號限制
其實這樣的情況下,賬號的作用更多是網站處於功能考慮的,反爬蟲只不過是順便完成的功能。具體的處理機制,可以通過模擬登錄。
推薦閱讀:
※python中 if-else 與 try-except的轉換 與while 與 whileTrue-try-except的轉換
※python爬取QQ音樂
※八、示例
※網易雲音樂Ajax Post參數加密方法
※初識Scrapy,在充滿爬蟲的世界裡做一個好公民