1. 反爬
有時(shí)候秦踪,我們利用 Selenium 自動(dòng)化爬取某些網(wǎng)站時(shí)掸茅,極有可能會(huì)遭遇反爬。
實(shí)際上景馁,我們使用默認(rèn)的方式初始化 WebDriver 打開一個(gè)網(wǎng)站逗鸣,下面這段 JS 代碼永遠(yuǎn)為 true,而手動(dòng)打開目標(biāo)網(wǎng)站的話透葛,則為:undefined
# 通過這段 JS 腳本區(qū)分是爬蟲還是人工操作
window.navigator.webdriver
稍微有一點(diǎn)反爬經(jīng)驗(yàn)的工程師利用上面的差別卿樱,很容易判斷訪問對(duì)象是否為一個(gè)爬蟲,然后對(duì)其做反爬處理萨蚕,返回一堆臟數(shù)據(jù)或各種驗(yàn)證碼蹄胰。
如果要實(shí)現(xiàn)后面的自動(dòng)化操作烤送,首先要解決的就是這個(gè)反爬的問題。
常見的反反爬方案包含:設(shè)置參數(shù) excludeSwitches妻往、mitmproxy 攔截過濾试和、cdp 命令,下面分別來說說好渠。
2.設(shè)置參數(shù) excludeSwitches
Chrome79 之前可以通過配置 ChromeOptions 驅(qū)動(dòng)參數(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")
這個(gè)參數(shù)是實(shí)驗(yàn)性參數(shù)杆烁,所以右上角會(huì)提示:請(qǐng)停用開發(fā)者模式運(yùn)行的擴(kuò)展程序,不能點(diǎn)擊停用烤芦。
這樣析校,設(shè)置這個(gè)參數(shù)后:
window.navigator.webdriver 的值就變成 undefined 了。
3. mitproxy 攔截
眾所周知绰播,mitproxy 可以攔截到網(wǎng)絡(luò)請(qǐng)求尚困,做其他處理事甜,這里只需要進(jìn)行 JS 代碼注入即可滔韵。
# 待執(zhí)行的 JS 代碼,修改 window.navigator.webdriver 的值
js_exec = 'Object.defineProperties(navigator,{webdriver:{get:() => false}});'
# 重寫 response,截獲網(wǎng)絡(luò)請(qǐng)求邦马,js注入
def response(slef,flow: mitmproxy.http.HTTPFlow):
if 'google' in flow.request.url:
flow.response.text = js_exec + flow.response.text
然后啟動(dòng) mitmdump
# 啟動(dòng)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() 方法可以在頁面還未加載之前随闽,運(yùn)行一段腳本掘宪。
如此蛾扇,我們只需要提前設(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")
本文轉(zhuǎn)自: AirPython微信公眾號(hào)Selenium 系列篇(六):反反爬篇
https://mp.weixin.qq.com/s/EzQZCWKaJFAXoafQhxMytA