點擊上方“Python自動化社區(qū)”检眯,選擇“加為星標(biāo)”
?第一時間關(guān)注 Python 自動化技術(shù)干貨煮盼!
系列導(dǎo)讀
1. 反爬
有時候,我們利用 Selenium 自動化爬取某些網(wǎng)站時躏救,極有可能會遭遇反爬。
實際上,我們使用默認(rèn)的方式初始化 WebDriver 打開一個網(wǎng)站潘飘,下面這段 JS 代碼永遠(yuǎn)為 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ù)稽屏,來達(dá)到反反爬的目的。
只需要將參數(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ā)者模式運行的擴(kuò)展程序获雕,不能點擊停用荒叼。
這樣,設(shè)置這個參數(shù)后:
window.navigator.webdriver 的值就變成 undefined 了典鸡。
3. mitproxy 攔截
眾所周知被廓,mitproxy 可以攔截到網(wǎng)絡(luò)請求,做其他處理萝玷,這里只需要進(jìn)行 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 自動化被反爬的問題直奋。
更多自動化相關(guān)的技術(shù)干貨,可以關(guān)注【 Python自動化社區(qū) 】來解鎖施禾。