背景
前一陣兒被某網站的 JS 反爬流程難住了,至今也沒明白它的反扒原理和攻破方法。最終找到了一個自動化指令碼工具 autoit 3,用一個笨方法將人手動點選瀏覽器的動作指令碼化,達到網頁資料獲取目的,拿到網頁檔案後,再用程式碼解析,曲線完成任務。
本文將介紹這個自動化的過程,並帶編寫一個完整的 autoit 3 爬蟲指令碼,希望對各位讀者朋友有所啟發。
自動化操作分析以國家資訊保安漏洞共享平臺為例,它在返回資料前發起了兩次 512 響應,第三次瀏覽器帶著動態生成的 Cookie 資訊才能得到資料。
切換為英文輸入法,保證瀏覽器輸入欄資訊正確;開啟 Chrome 瀏覽器;向瀏覽器位址列輸入目標 URL;按下 Enter 鍵,等待 2 秒保證頁面資料載入完成;按下 Ctrl +S 鍵,並向儲存路徑傳送儲存檔名稱,等待“儲存”操作完成;按下 End 鍵盤,定位到頁面底部;按下反向 Tab 鍵 15 次,定位到 “下頁” 按鈕;按下 Enter 鍵,請求下一頁資料;迴圈 5-8 這個過程 N 次,N=需要爬的頁數。這個流程,對其他高反扒的資訊釋出網站,也是適用的。
編寫自動化指令碼按照上面的流程,編寫 autoit 自動化指令碼,建立一個 myspider.au3 檔案:
#include <AutoItConstants.au3>;;切換為英文輸入法,保證瀏覽器輸入正常$hWnd = WinGetHandle("[ACTIVE]");$hWnd 為目標視窗控制代碼,這裡設定的是當前活動視窗$ret = DllCall("user32.dll", "long", "LoadKeyboardLayout", "str", "08040804", "int", 1 + 0)DllCall("user32.dll", "ptr", "SendMessage", "hwnd", $hWnd, "int", 0x50, "int", 1, "int", $ret[0])$url = "https://www.cnvd.org.cn/flaw/list.htm"spiderData($url)Func spiderData($url) ;;開啟 Chrome 瀏覽器視窗 $chromePath = "C:\Users\admin\AppData\Local\Google\Chrome\Application\chrome.exe" Run($chromePath) ;;登入視窗顯示 WinWaitActive("[CLASS:Chrome_WidgetWin_1]") ;; 休息2000毫秒 Sleep(2000) ;; 移動視窗 WinMove("[CLASS:Chrome_WidgetWin_1]", "開啟新的標籤頁 - Google Chrome", 0, 0,1200,740,2) ;; 休息500毫秒 Sleep(500) ;;位址列輸入URL 並按下 Enter 鍵 Send($url) Sleep(500) Send("{enter}") Sleep(3000) ;; 迴圈爬取需要的頁數,測試只爬3頁 For $i = 1 To 3 Step 1 ;;開啟右鍵另存為按鈕: Ctrl+S send("^s") Sleep(2000) WinWait("[CLASS:#32770]","",10) ;;將儲存路徑設定到另存為元件輸入框 Edit1 裡 $timeNow = @YEAR & "" & @MON & "" & @MDAY & "" & @HOUR & "" & @MIN $savePath = "F:\A2021Study\ListData\" &$timeNow & "_page" & $i & ".html" ControlSetText("另存為","", "Edit1", $savePath) ;;點選確定 ControlClick("另存為","","Button2") ;;再次確定 WinWait("[CLASS:#32770]","",10) ControlClick("確認另存為","","Button1") ;; 等待儲存操作完成 Sleep(3000) ;; 定位到下一頁按鈕,並觸發點選下一頁 send("{END}") Send("+{TAB 15}") Send("{enter}") ;;點選確定後,等待網頁載入完成 Sleep(3000) Next ;; 整個操作完成,則關閉瀏覽器 Send("^w")EndFunc
指令碼編寫過程中,有幾點需要注意:
第一,輸入法切換很重要,否則 URL 位址列的值很容易亂;第二, windows 的檔案路徑是反斜槓 \ ,否則會導致另存為的路徑無法識別;第三,幫助文件裡面提供的關閉方法是 WinClose ,但是反覆測試,確定這個方法不靠譜,要麼會引起瀏覽器異常關閉導致下次開啟會恢復上次的網址;要麼完全不生效。迂迴的解決辦法是用關閉按鍵 Ctrl+W ,完成了正常關閉的目的。因為爬蟲要作為定時任務執行的,為避免開啟太多瀏覽器視窗,因此需要在指令碼結束時關閉瀏覽器。
啟示錄資料爬取一般分為列表頁和詳情頁,定位點選每一條詳情的過程比較麻煩,所以爬取詳情頁面的和列表分開,用 Java 程式碼解析所有詳情 URL 後,再由另一個 autoit 指令碼去獲取詳情頁面,這個流程大家可以自己寫一下,這裡就不詳細介紹了。
最後再彙總下整個爬取的流程:
第一步,執行爬取列表的 autoit 指令碼,得到列表頁面 html;第二步,解析列表頁 html ,得到所有詳情頁面的 URL ,寫入到檔案中;第三步,執行爬取詳情頁面的 autoit 指令碼,它遍歷第二步的目標 URL ,得到詳情頁 html ;第四步,解析詳情頁 html 檔案,得到詳情資料。
總控流程、第二步和第四步的解析都用 Java 程式碼完成,用 Runtime.getRuntime().exec("cmd /c E:\A2021Study\Autoit3\myspider.au3") 呼叫指令碼,檔案路徑是反斜槓。
這個方法雖然有點笨,但完全是人工操作瀏覽器,能夠對抗反爬蟲策略,感興趣的朋友可以執行下本文的指令碼試試。
autoit 還是蠻有意思的,語法也很簡單,DirCreate 建立檔案,iniread 讀取配置項,一行程式碼頂 Java 幾十行,不得不承認 Java 操作檔案才是最麻煩的哇!