使用Selenium修改Navigator对象webdriver属性失败及超时问题求助
首先,你遇到的两个核心问题:一是execute_async_script导致的超时错误,二是修改navigator.webdriver的时机太晚,网站已经完成检测了。
为什么会超时?
你用了execute_async_script来执行注入的JS,但这个方法的设计是需要脚本主动调用回调函数来告诉Selenium脚本执行完成。你的代码里没有调用这个回调,所以Selenium一直在等,最后就超时抛出TimeoutException了。如果只是执行同步的脚本,应该用execute_script代替。
但就算换成execute_script,你现在的写法还是有问题:你是先加载页面,再修改navigator.webdriver,而目标网站很可能在页面加载的初期阶段就已经检测了这个属性,等你页面加载完再改,早就被网站的反爬机制抓到了。
正确的解决思路
要在页面开始加载之前就把navigator.webdriver改成false,让网站的检测脚本一开始看到的就是修改后的值。下面给你两种可行的方法:
方法1:直接修改Firefox的偏好设置
Firefox本身有个内置的偏好项dom.webdriver.enabled,当用Selenium启动时默认是true,把它设为false就能直接让navigator.webdriver返回false,不需要手动注入JS。
修改后的代码如下:
from selenium import webdriver from selenium.webdriver.firefox.options import Options firefox_binary = '/usr/bin/firefox' options = Options() # 添加Firefox偏好设置,禁用webdriver标志 options.set_preference("dom.webdriver.enabled", False) options.set_preference('useAutomationExtension', False) driver = webdriver.Firefox(executable_path=r'/home/kkkk/ggecko/geckodriver', firefox_binary=firefox_binary, options=options) driver.get('https://auth.citromail.hu/regisztracio/') # 验证:在浏览器控制台执行console.log(navigator.webdriver)应该返回false
方法2:使用CDP提前注入脚本(更通用)
如果方法1不生效,可以用Chrome DevTools Protocol(Firefox 63+支持)的Page.addScriptToEvaluateOnNewDocument命令,让脚本在每个新页面加载时最先执行,覆盖navigator.webdriver属性。
代码示例:
from selenium import webdriver from selenium.webdriver.firefox.options import Options firefox_binary = '/usr/bin/firefox' options = Options() # 启用CDP支持 options.add_argument("--remote-debugging-port=9222") driver = webdriver.Firefox(executable_path=r'/home/kkkk/ggecko/geckodriver', firefox_binary=firefox_binary, options=options) # 注入页面加载前执行的脚本 driver.execute_cdp_cmd("Page.addScriptToEvaluateOnNewDocument", { "source": """ Object.defineProperty(navigator, 'webdriver', { get: () => false }); """ }) driver.get('https://auth.citromail.hu/regisztracio/')
额外注意事项
- 你的Selenium版本看起来比较旧(适配Python3.5的版本),如果遇到CDP相关问题,可以尝试升级到兼容的Selenium版本(不过Python3.5已停止支持,能升级的话尽量更新Python版本)。
- 有些网站还会检测其他指纹特征,比如
window.navigator.plugins、navigator.languages等,如果这个方法还不行,可能需要进一步伪装这些属性,但先解决webdriver这个最明显的特征。
内容的提问来源于stack exchange,提问作者Nesa

