Selenium 系列篇(六):反反爬篇
點擊上方“AirPython”,選擇“加為星標(biāo)”
第一時間關(guān)注 Python 技術(shù)干貨!

1. 反爬
有時候,我們利用 Selenium 自動化爬取某些網(wǎng)站時,極有可能會遭遇反爬。
實際上,我們使用默認的方式初始化 WebDriver 打開一個網(wǎng)站,下面這段 JS 代碼永遠為 true,而手動打開目標(biāo)網(wǎng)站的話,則為:undefined
#?通過這段?JS?腳本區(qū)分是爬蟲還是人工操作
window.navigator.webdriver?稍微有一點反爬經(jīng)驗的工程師利用上面的差別,很容易判斷訪問對象是否為一個爬蟲,然后對其做反爬處理,返回一堆臟數(shù)據(jù)或各種驗證碼。

如果要實現(xiàn)后面的自動化操作,首先要解決的就是這個反爬的問題。
常見的反反爬方案包含:設(shè)置參數(shù)?excludeSwitches、mitmproxy 攔截過濾、cdp 命令,下面分別來說說。
2.設(shè)置參數(shù)?excludeSwitches
Chrome79 之前可以通過配置 ChromeOptions 驅(qū)動參數(shù),來達到反反爬的目的。
只需要將參數(shù)打開,設(shè)置 excludeSwitches 值為 enable-automation 即可。
from?selenium.webdriver?import?Chrome
from?selenium.webdriver?import?ChromeOptions
option?=?ChromeOptions()
#?打開參數(shù)
option.add_experimental_option('excludeSwitches',?['enable-automation'])
driver?=?Chrome(options=option)
driver.implicitly_wait(10)
driver.get("http://www.google.com")
這個參數(shù)是實驗性參數(shù),所以右上角會提示:請停用開發(fā)者模式運行的擴展程序,不能點擊停用。
這樣,設(shè)置這個參數(shù)后:
window.navigator.webdriver 的值就變成 undefined 了。
3. mitproxy 攔截
眾所周知,mitproxy 可以攔截到網(wǎng)絡(luò)請求,做其他處理,這里只需要進行 JS 代碼注入即可。
#?待執(zhí)行的?JS?代碼,修改?window.navigator.webdriver?的值
js_exec?=?'Object.defineProperties(navigator,{webdriver:{get:()?=>?false}});'
#?重寫?response,截獲網(wǎng)絡(luò)請求,js注入
def?response(slef,flow:?mitmproxy.http.HTTPFlow):
????????if?'google'?in?flow.request.url:
????????????????flow.response.text?=?js_exec?+?flow.response.text
然后啟動 mitmdump
#?啟動mitmproxy
mitmdump?-p?8888?-s?111.py?
最后,配置 ChromeOptions 指向 mitmdump代碼即可。
#?配置ChromeOptions
option.add_argument("--proxy-server=http://127.0.0.1:8888")4. cdp 命令
cdp 全稱是:Chrome Devtools-Protocol
通過 addScriptToEvaluateOnNewDocument()?方法可以在頁面還未加載之前,運行一段腳本。
如此,我們只需要提前設(shè)置:
window.navigator.webdriver 的值為 undefined 即可。
from?selenium.webdriver?import?Chrome
from?selenium.webdriver?import?ChromeOptions
option?=?ChromeOptions()
#?打開參數(shù)
#?option.add_argument("--proxy-server=http://127.0.0.1:8888")
#?driver?=?Chrome(options=option)
driver?=?Chrome()
driver.execute_cdp_cmd("Page.addScriptToEvaluateOnNewDocument",?{
??"source":?"""
????Object.defineProperty(navigator,?'webdriver',?{
??????get:?()?=>?undefined
????})
??"""
})
driver.implicitly_wait(10)
driver.get("http://www.google.com")5. 其他
通過上面的 3 種方法可以很好的解決 Selenium 自動化被反爬的問題。

???
