爬蟲驗證碼總是出錯 常用的反爬蟲封禁手段概覽

2021-10-11 19:16:34 字數 3117 閱讀 7573

一般的**都不歡迎爬蟲流量,消耗伺服器資源不說,還會把自己的商業資料爬走,於是就誕生了各種各樣的反爬蟲手段。

從介面的角度來說,匿名的介面一定是可以濫用的,只是破解成本的問題,而有登入狀態的介面一般不容易被濫用。客戶端反爬一定是可以破解的,服務端反爬往往不一定能夠破解。

這篇文章有點長,沒時間看的同學可以直接拉到最後看總結的思維導圖。

瀏覽器反爬的第乙個手段就是「驗明正身」,也就是說驗證是否是瀏覽器發出的請求

驗證是否是瀏覽器,甚至於驗證是否是自動控制的瀏覽器

前端通過 js 生成 token

對於驗證是否是瀏覽器來說,我們可以直接使用 selenium 或者 puppeteer 這種可以程式化控制的庫來爬取**。有一些**還會檢測是不是採用了這種自動化的手段,至於如何繞過這些限制又是乙個大問題了,會在後面的文章中詳細闡述。

有一些 api 訪問必須通過token,如果含有合法這個 token 就認為訪問是合法的。一般來說在使用了 token 驗證訪問合法性的時候,服務端就不太會再對 ip 等做限制了。

token 的計算過程往往有三個因素需要參與,分別是 key、secret 和簽名演算法。比如說下面的 api:

secret = md5(sorted(["k=v" for k, v in params] + ["secret=123456"]).join("") + )
也就是把所有引數都排序之後,拼接成字串然後再計算某個hash值,作為token附在引數後面。

一般來說常用的簽名演算法都是這樣實現的:

引數中加上時間戳,同時附在請求上,這樣伺服器可以只接受當前時間附近的真實請求,從而避免某個請求被儲存下來,用作重放攻擊。

新增引數secret=123456到需要計算的引數中,但是secret並不會出現在請求中。

把所有需要加密的引數都按照字典排序,然後拼接成字串,這樣是為了計算出來的值唯一。

計算出的token也附在請求上,一起發給伺服器。

對於網頁中通過 ajax 請求 api 來說,因為 js 實際上相當於是原始碼公開的,所以隱藏secret和演算法實際上是不現實的。這時候可以有兩種做法,一種是把secret和加密演算法等放到flash裡面去,flash是可以編譯成二進位制的,所以相對來說更安全一些,不過隨著flash的死亡,這種做法應該是逐漸淘汰了。另一種做法是secret動態獲取,控制secret的來提高破解難度,同時把加密演算法做一些混淆。

更嚴厲一點的話,可以限制只有登入使用者可以訪問某些敏感介面,這樣就完全由服務端來控制介面的訪問量了,只需要注意使用者註冊的介面不要被濫用即可。這就是服務端的驗證了,後面會繼續討論。

關於 js 的反編譯和破解也是乙個很大的話題了,有機會了再寫。

比如**h5站的介面:

當請求不帶任何cookie時,會返回乙個_m_h5_tk_m_h5_tk_enc,通過下面的演算法算出sign值再次請求

echo -n 'ddc882e0e69bb8babbfdecc479439252&1450260485494&12574478&'|md5sum|cut -d ' ' -f1
既然客戶端的資訊都是可以偽造的,那麼我們乾脆不相信客戶端的資訊了,在服務端統計一些無法偽造的資訊。比如** ip 和登入賬戶資訊。

這種方法簡單粗暴,直接根據**ip來判定是否是同乙個使用者,如果訪問過快,遮蔽請求或者需要輸入驗證碼。但是有乙個問題,好多學校或者公司都是使用為數不多的幾個ip位址來作為出口ip,方便管理,如果這種地方有一兩個人在惡意請求,那麼可能遮蔽會造成很多人訪問異常。

有的大型**甚至會對於民用ip和機房ip做出區別對待,比如 google。

對於這種限制來說,可以放慢請求速度,或者使用多個**ip來偽裝自己。**池的構建也是單獨一篇文章才能講清楚的,敬請期待。

不少**往往不會直接把某個 ip 完全限制,而是在發現可疑訪問時彈出驗證碼,這時候可以自己ocr識別,訓練深度學習模型識別驗證碼(比如使用 cnn)或者直接對接打碼平台。

關於不同型別的驗證碼和深度學習後面有時間再寫。

上面說過直接通過 ip 來識別使用者的話比較暴力,可能誤傷,另一種方法就是通過 cookie 來標示使用者,如果有乙個使用者訪問過多的話,就對這個cookie做限制。

對於這種限制來說,可以直接每次請求不帶 cookie,或者預先多申請一些 cookie,然後負載均衡一下。

除了在服務端生成 cookie 之外,**還可以選擇在客戶端通過複雜的演算法來生成 cookie,不過這就是客戶端反爬的情況了,對於這種還是要看懂對方的 js 還好。或者不在乎效率的話,有的時候可以直接用控制瀏覽器訪問解決。

對於傳統的靜態頁面的限制和破解基本上就是這些方法。不過現在很多頁面都是操作豐富的動態頁面,也就是我們感興趣的訊息可能是通過ajax載入的,我們只需要訪問這個api就可以了。

上面說的通過 cookies 來識別客戶其實指的是匿名賬戶的 cookies。好多**的資源都是需要登入賬戶來訪問的,這時候首先要考慮的是能不能大批量偽造賬戶,可以借助於匿名郵箱和手機驗證碼接碼平台等。

如果不能大規模的註冊賬戶,那麼還需要的是購買賬戶了,這個就看抓取的 roi(投資回報比)是什麼了。

最簡單的情況下,**對登入使用者沒有限制,那麼買乙個賬戶總是值的。

對於賬戶除了整體的頻次控制以外,往往還會限制登入的 ip。比如說賬戶獲得的 cookie 是和 ip 繫結的,某個 ip 每天只能登入若干個賬戶等等。

上面的反爬和反反爬手段可以總結如下:

除了上述措施之外,還要避免一些設計上的缺陷被爬蟲濫用。下面舉幾個例子。

什麼值得買的評測頁面, ,這個鏈結的最後乙個數字就是評測的問題id,大小才不過幾萬,也就是說,我只要遍歷一下這個數字,就可以把「什麼值得買」這個**的所有評測都爬取一遍,這個是在太容易被利用了。

對於這個問題,可以不要直接使用資料庫的主鍵作為頁面的id,而是盡量使用沒有規律的數字(比如uuid)或者至少大一點的數字作為id,避免被窮舉遍歷。

鏈家的二手房頁面, ,這個頁面的id就比較大了,但是我們沒辦法去遍歷這樣乙個數字。這時候可以從列表頁入手, ,只要從頁面上找到所有二手房的頁面位址就可以了。

有一些 api 沒有任何防護,對於這種 api 直接刷就好了,不過可能有的 api 會有根據 ip 的頻次限制。

爬蟲反爬之驗證碼

if name main chaojiying chaojiying client 超級鷹使用者名稱 超級鷹使用者名稱的密碼 96001 使用者中心 軟體id 生成乙個替換 96001 本地檔案路徑 來替換 a.jpg 有時win系統須要 print chaojiying.postpic im,19...

爬蟲 驗證碼處理

關的門戶 在進行登入的時候,如果使用者連續登入的次數超過3次或者5次的時候,就會在登入頁中動態生成驗證碼。通過驗證碼達到分流和反爬的效果。雲打碼平台處理驗證碼的實現流程 3.可以將驗證碼提交給三方平台進行識別,返回驗證碼上的資料值 雲打碼平台 1.在官網中進行註冊 普通使用者和開發者使用者 2.登入...

爬蟲之驗證碼破解(四)

註冊超級鷹賬戶超級鷹官網 官網有詳細使用說明,以下是api使用方法。from hashlib import md5 class chaojiying client object def init self,username,password,soft id self.username usernam...