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

現在的網頁代碼搞得越來越複雜,除了使用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逆向方法論-反爬蟲的四種常見方式

第一次打開“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逆向方法論-反爬蟲的四種常見方式

三、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後的參數,把這些參數都帶上就萬事大吉啦。

結尾

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


分享到:


相關文章: