1. 项目概述:当Selenium遇上反爬虫检测
如果你用Selenium写过爬虫,大概率遇到过这种情况:脚本跑得好好的,突然就访问不了了,或者页面返回一堆乱码,甚至直接弹出一个验证码。这背后,往往是网站的反爬虫机制检测到了你正在使用自动化工具。最经典的“指纹”之一,就是 navigator.webdriver 属性。在普通浏览器里,这个属性是 undefined 或者 false ,但在Selenium控制的浏览器里,它会被设置为 true 。对于反爬虫系统来说,这就像在脑门上贴了“我是机器人”的标签,一抓一个准。
今天要聊的,就是如何把这个标签撕下来,或者至少伪装一下。我会分享三种经过实战检验的隐藏或修改WebDriver属性的技巧,从简单到复杂,覆盖不同场景。同时,鉴于ChromeDriver的版本匹配是个老生常谈的坑,我也会附上最新的、稳定的ChromeDriver配置方法,确保你的环境一步到位。无论你是刚入门爬虫的新手,还是正在为某个顽固网站头疼的老手,这些技巧都能帮你绕过最基础的自动化检测,让爬虫跑得更稳。
2. 核心原理:为什么 webdriver 属性会暴露你?
在深入技巧之前,我们得先搞清楚对手是怎么发现我们的。这不仅仅是知道一个属性,更要理解浏览器自动化工具与原生浏览器的根本区别。
2.1 WebDriver协议与浏览器指纹
Selenium WebDriver本质上是通过一套名为WebDriver的协议来控制浏览器的。当你启动 ChromeDriver 时,它会创建一个特殊的Chrome实例,这个实例内部启用了一系列用于远程控制和自动化测试的接口。作为协议的一部分,浏览器需要向客户端(即你的脚本)报告其自动化能力, navigator.webdriver 属性就是其中一个标志位。
在原生Chrome中,这个属性根本不存在( undefined )或者是 false ,因为普通用户不需要自动化控制。而一旦通过WebDriver启动,Chrome就会将这个属性设置为 true 。反爬虫系统通过执行一段JavaScript(比如 return navigator.webdriver )来探测这个属性,如果返回 true ,就可以高度怀疑当前会话来自自动化脚本。
2.2 检测手段的演进
早期的反爬虫可能只检查这一个属性,但现在的手段要复杂得多。除了 webdriver ,它们还会检查一系列“自动化特征”:
- 浏览器特征参数 :例如通过 –enable-automation 或 –headless 等命令行参数启动的浏览器。
- 插件与扩展 :检查是否存在常见的自动化测试插件。
- 行为模式 :鼠标移动轨迹是否过于线性、点击速度是否恒定且过快、页面停留时间是否异常等。
- 其他JavaScript属性 :如 window.chrome 对象下的某些方法、 document.$cdc_asdjflasutopfhvcZLmcfl_ 这类WebDriver注入的特殊变量。
因此,仅仅隐藏 webdriver 属性可能不足以应对高级别的反爬虫,但它是最基础、最关键的一步。解决了它,就相当于拆掉了最明显的一个警报器。
2.3 我们的应对思路
我们的目标不是禁用WebDriver协议(那会导致Selenium无法工作),而是让浏览器在JavaScript运行时环境中,看起来像一个普通的人类用户浏览器。主要有三种思路:
下面,我们就围绕这三种思路,展开具体的实战技巧。
3. 技巧一:通过启动选项隐藏自动化特征(基础版)
这是最简单直接的方法,适合应对检测逻辑比较简单的网站。核心是使用 ChromeOptions (或 Options )来添加实验性参数。
3.1 关键参数解析
我们主要通过 add_experimental_option 方法来添加 excludeSwitches 和 useAutomationExtension 选项。
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
chrome_options = Options()
# 关键配置:排除“启用自动化”的开关,并禁用自动化扩展
chrome_options.add_experimental_option(\’excludeSwitches\’, [\’enable-automation\’])
chrome_options.add_experimental_option(\’useAutomationExtension\’, False)
# 可选但推荐:避免被检测到“受控软件”
prefs = {
\”credentials_enable_service\”: False,
\”profile.password_manager_enabled\”: False
}
chrome_options.add_experimental_option(\’prefs\’, prefs)
driver = w

