反爬蟲的四種常見方式-JS逆向方法論

王平發表於2019-08-19

現在的網頁程式碼搞得越來越複雜,除了使用vue等前端框架讓開發變得容易外,主要就是為了防爬蟲,所以寫爬蟲下的功夫就越來越多。攻和防在互相廝殺中結下孽緣卻又相互提升著彼此。

本文就JS反爬蟲的策略展開討論,看看這中間都有著怎樣的方法。

JS逆向方法論-反爬蟲的四種常見方式

一 、JS寫cookie

我們要寫爬蟲抓某個網頁裡面的資料,無非是開啟網頁,看看原始碼,如果html裡面有我們要的資料,那就簡單了。用requests請求網址得到網頁原始碼然後解析提取。

等等!requests得到的網頁是一對JS,跟瀏覽器開啟看到的網頁原始碼完全不一樣!這種情況,往往是瀏覽器執行這段JS生成一個(或多個)cookie再帶著這個cookie做二次請求。伺服器那邊收到這個cookie就認為你的訪問是透過瀏覽器過來的合法訪問。

其實,你在瀏覽器(chrome、Firefox都可以)裡可以看到這一過程。首先把Chrome瀏覽器儲存的該網站的cookie刪除,按F12到Network視窗,把“preserve log”選中(Firefox是“Persist logs”),重新整理網頁,這樣我們就可以看到歷史的Network請求記錄。比如下圖:

js寫cookies

第一次開啟“index.html”頁面時返回的是521, 內容是一段JS程式碼;第二次請求這個頁面就得到了正常的HTML。檢視兩次請求的cookies,可以發現第二次請求時帶上了一個cookie,而這個cookie並不是第一次請求時伺服器發過來的。其實它就是JS生成的。

對策就是,研究那段JS,找到它生成cookie的演算法,爬蟲就可以解決這個問題。

 

二、JS加密ajax請求引數

寫爬蟲抓某個網頁裡面的資料,發現網頁原始碼裡面沒有我們要的資料,那就有點麻煩了。那些資料往往是ajax請求得到的。但是也不用怕,按F12開啟Network視窗,重新整理網頁看看載入這個網頁都下載了哪些URL,我們要的資料就在某個URL請求的結果裡面。這類URL在Chrome的Network裡面的型別大多是XHR。透過觀察它們的“Response”就可以發現我們要的資料。

然而事情往往不是這麼順利,這個URL包含很多引數,某個引數是一串看上去無意義的字串。這個字串很可能是JS透過一個加密演算法得到的,伺服器也會透過同樣的演算法進行驗證,驗證透過了才認為你這是從瀏覽器來的請求。我們可以把這個URL複製到位址列,把那個引數隨便改個字母,訪問一下看看是不是能得到正確的結果,由此來驗證它是否是很重要的加密引數。

對於這樣的加密引數,對策是透過debug JS來找到對應的JS加密演算法。其中關鍵的是在Chrome裡面設定“XHR/fetch Breakpoints”。

js-ajax請求

 

三、JS反除錯(反debug)

前面我們都用到了Chrome 的F12去檢視網頁載入的過程,或者是除錯JS的執行過程。這種方法用多了,網站就加了反除錯的策略,只有我們開啟F12,就會暫停在一個“debugger”程式碼行,無論怎樣都跳不出去。它看起來像下面這樣:

js反除錯

不管我們點選多少次繼續執行,它一直在這個“debugger”這裡,每次都會多出一個VMxx的標籤,觀察“Call Stack”發現它好像陷入了一個函式的遞迴呼叫。這個“debugger”讓我們無法除錯JS。但是關掉F12視窗,網頁就正常載入了。

解決這種JS反除錯的方法我們稱之為“反-反除錯”,其策略是:透過“Call Stack”找到把我們帶入死迴圈的函式,重新定義它。

這樣的函式幾乎沒有任何其它功能只是給我們設定的陷阱。我們可以把這個函式在“Console”裡面重新定義,比如把它重新定義為空函式,這樣再執行它時就什麼都不做,也就不會把我們帶人陷阱。在這個函式呼叫的地方打個“Breakpoint”。因為我們已經在陷阱裡面了,所以要重新整理頁面,JS的執行應該停止在設定的斷點處,此時該函式尚未執行,我們在Console裡面重新定義它,繼續執行就可以跳過該陷阱。

 

四、JS傳送滑鼠點選事件

還有些網站,它的反爬都不是上面的方式。你從瀏覽器可以開啟正常的頁面,而在requests裡面卻被要求輸入驗證碼或重定向其它網頁。起初你可能一頭霧水,但不要怕,認真看看“Network”或許能發現些線索。比如下面這個Network流裡面的資訊:

js滑鼠軌跡跟蹤

認真觀察後發現,每點選頁面的的連結,它都會做一個“cl.gif”的請求,它看上去是下載一個gif圖片,然而並不是。它請求時傳送的引數非常多,而且這些引數都是當前頁面的資訊。比如包含了被點選的連結等等。

我們先來梳理一下它的邏輯。JS會響應連結被點選的事件,在開啟連結前,先訪問cl.gif,把當前的資訊傳送給伺服器,然後再開啟被點選的連結。伺服器收到被點選連結的請求,會看看之前是不是已經透過cl.gif把對應資訊發過來,如果發過來了就認為是合法的瀏覽器訪問,給出正常的網頁內容。

因為requests沒有滑鼠事件響應就沒有訪問cl.gif的過程就直接訪問連結,伺服器就拒絕服務。

明白了這個過程,我們不難拿出對策,幾乎不需要研究JS內容(JS也有可能對被點選連結進行修改哦)就可以繞過這個反爬策略,無非是在訪問連結前先訪問一下cl.gif即可。關鍵是要研究cl.gif後的引數,把這些引數都帶上就萬事大吉啦。

 

結尾

爬蟲和網站是一對冤家,相剋相生。爬蟲知道了反爬策略就可以做成響應的反-反爬策略;網站知道了爬蟲的反-反爬策略就可以做一個“反-反-反爬”策略……道高一尺魔高一丈,兩者的鬥爭也不會結束。

猿人學banner宣傳圖

我的公眾號:猿人學 Python 上會分享更多心得體會,敬請關注。

***版權申明:若沒有特殊說明,文章皆是猿人學 yuanrenxue.com 原創,沒有猿人學授權,請勿以任何形式轉載。***

相關文章