淘寶登陸對selenium爬蟲的封殺和反爬


眾所周知目前使用selenium打開瀏覽器訪問淘寶,會彈出登錄頁面,不管你是手動還是自動登錄一律都是在滑塊驗證碼時不通過,今天花了幾個小時分析了一下,也只是對其整體有了個認識

總體上淘寶的反爬蟲思路是:基於用戶身份的ua算法,來識別瀏覽器是正常狀態還是非正常狀態。

ua:UA的中文翻譯是用戶代理,全稱是User Agent,簡單來說是終端的環境信息如:Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN) AppleWebKit/533.21.1 (KHTML, like Gecko) Version/5.0.5 Safari/533.21.1

它是一個特殊字符串頭,使得服務器能夠識別客戶使用的操作系統及版本、CPU 類型、瀏覽器及版本、瀏覽器渲染引擎、瀏覽器語言、瀏覽器插件等 

但是這只是一般意義上的ua參數,實際使用中ua代表了一個終端的標識,ID代表了一個用戶的標識,隨着網絡安全的深入,ua已經不再是一串環境的信息字符串,而是開發者單獨發開出來的一套甄別終端的算法,成為了單獨執行的js文件

當訪問淘寶登錄界面會發送一個POST請求,這個post請求中有一個關鍵信息ua

ua參數很長一串,看似像RSA加密過的,並且這個參數時刻變化着,兩次生成的ua都不相同:

只有前幾位是相同的,其他完全不同,這個post請求中有一個關鍵信息ua,至於ua怎么生成目前還未分析出,他的出處在全局對象window[UA_Opt.LogVal]、或者window["_n"],並且每次輸出都不一樣。

 瀏覽器window對象,他是出於一個私有屬性_n,但是怎么做到每次輸出的值都不一樣的。

使用正常瀏覽器打開瀏覽器的,window.navigator.webdriver這個值為undefined,在JavaScript中undefined為未定義,即該值不存在,而false表示一布爾值。

 而使用selenium打開的瀏覽器,這個值為true

所以淘寶就是根據這個值進行滑塊的彈出和不彈出,當拖動滑塊的時候,會有一個滑塊驗證的請求,請求中有個參數t

這個t參數就是上面所提到的ua,也就是在驗證滑塊是否正確的時候淘寶后台還會對ua驗證一番,檢驗是否為正確的標識,一切selenium打開的瀏覽器里面'browser': {'ie': False, 'chrome': True, 'webdriver': True},當然webdriver是比較關鍵的參考標准,除此還有幾十個其他異於正常瀏覽器的屬性,很明顯這些信息被加密在ua參數之中。淘寶后台在收到滑塊驗證信息的時候,會同時對ua經行驗證,所有含有webdriver=True的驗證都會被返回code=300。

 

 

現在我們大致就清楚了淘寶對selenium的檢測:通過本地的js算法生成ua,ua里面含有瀏覽器信息,甚至含有當前地址,當輸入完賬號后會把賬號和ua一起post給服務器,服務器解析ua后通過智能算法識別是否是常用登陸地、常用瀏覽器、環境有無異常,selenium打開的瀏覽器是異常瀏覽器,一定會返回滑塊驗證,當完成驗證后會再把ua和滑動的軌跡發給后台,后台在檢測ua,一旦含有異常信息就返回code=300,驗證失敗。

那么問題來了,怎么來避開滑塊驗證呢?

一、WebDriver規范

 

根據WebDriver規范(https://w3c.github.io/webdriver/#x4-interface)的描述,WebDriver定義了一個標准方法,以便於文檔(document)判斷當前瀏覽器處於自動化控制之中。

這個方法就是檢測window.navigator.webdriver的值,正常情況下其值為undefined,自動化控制下為true。注意,正常情況下不是false,在JavaScript中undefined為未定義,即該值不存在,而false表示一布爾值。

附上規范原文:

 

The webdriver-active flag is set to true when the user agent is under remote control. It is initially false.
Defines a standard way for co-operating user agents to inform the document that it is controlled by WebDriver, for example so that alternate code paths can be triggered during automation.

二、如何來解除這個規范呢

舊版本

版本79.0.3945.16之前,可用如下方法:

from selenium import webdriver

options = webdriver.ChromeOptions()
options.add_argument("start-maximized")
options.add_experimental_option("excludeSwitches", ["enable-automation"])
options.add_experimental_option("useAutomationExtension", False)

driver = webdriver.Chrome(options=options)
driver.get("YOUR_URL")
# 在控制台中驗證window.navigator.webdriver的值為undefined。
driver.quit()

新版本

版本79.0.3945.16之后,ChromeDriver修正了這一“問題”。

根據注記原文:

Resolved issue 3133: window.navigator.webdriver is undefined when "enable-automation" is excluded in non-headless mode (should be true) [Pri-2]

如何破解?

execute_cdp_cmd函數來幫忙!cdp即Chrome DevTools Protocal,Chrome開發者工具協議。

通過該函數在文檔加載前注入一段js代碼以消去webdriver值。

from selenium import webdriver

driver = webdriver.Chrome()
script = '''
Object.defineProperty(navigator, 'webdriver', {
    get: () => undefined
})
'''
driver.execute_cdp_cmd("Page.addScriptToEvaluateOnNewDocument", {"source": script})
driver.get("YOUR_URL")
# 在控制台中驗證window.navigator.webdriver的值為undefined。
driver.quit()

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM