浏览器自动化检测解决方案
概述
本文档记录了针对网站反自动化检测的完整解决方案,适用于 OpenClaw 项目。主要以 Boss直聘 (zhipin.com) 为案例,但原理适用于其他有类似检测的网站。
一、问题背景
现代网站使用多种技术检测自动化浏览器:
| 检测类型 |
说明 |
检测方式 |
| navigator.webdriver |
Puppeteer/Playwright 等添加的自动化标识 |
'webdriver' in navigator |
| CDP 变量 |
Chrome DevTools Protocol 注入的全局变量 |
window.cdc_adoQpoasnfa76pfcZLmcfl_* |
| headless 模式 |
无头浏览器特征检测 |
navigator.plugins.length === 0 |
| 浏览器指纹 |
WebGL、Canvas、字体等指纹 |
多维度综合检测 |
| 行为分析 |
访问频率、鼠标轨迹等 |
机器学习/规则引擎 |
二、问题分析
2.1 navigator.webdriver 检测
原理:Puppeteer/Playeteer 启动浏览器时,会在 navigator 对象上添加 webdriver 属性。
1 2 3 4
| Object.defineProperty(navigator, 'webdriver', { get: () => true });
|
关键发现:
navigator.webdriver 返回 false,但属性本身存在
- 网站使用
'webdriver' in navigator 检测,而非 navigator.webdriver
Object.defineProperty 定义不可配置的属性仍无效
delete navigator.webdriver 无法删除 Puppeteer 添加的属性
2.2 CDP 变量检测
Puppeteer 会在 window 对象上添加:
1 2 3
| window.cdc_adoQpoasnfa76pfcZLmcfl_Array window.cdc_adoQpoasnfa76pfcZLmcfl_Promise window.cdc_adoQpoasnfa76pfcZLmcfl_Symbol
|
这些变量名是 Puppeteer 的特征签名。
2.3 headless 模式检测
| 模式 |
行为 |
headless: true |
立即被重定向到 about:blank |
headless: 'new' |
页面可加载,但可能触发安全验证 |
headless: false |
页面可加载,但触发 IP 安全验证 |
三、解决方案
3.1 初级方案:禁用自动化特征 (不推荐)
1 2 3 4 5 6
| browser = await puppeteer.launch({ headless: 'new', args: [ '--disable-blink-features=AutomationControlled' ] });
|
结果:部分有效,但无法完全绕过检测。
3.2 中级方案:使用真实浏览器用户数据 (部分有效)
1 2 3 4 5 6 7 8 9 10 11
| const EDGE_USER_DATA = process.env.HOME + '/Library/Application Support/Microsoft/Edge/User Data';
browser = await puppeteer.launch({ headless: 'new', executablePath: EDGE_PATH, args: [ '--disable-blink-features=AutomationControlled', '--no-first-run', '--user-data-dir=' + EDGE_USER_DATA ] });
|
结果:页面可以加载,但 IP 验证仍可能触发。
核心思路:使用用户已登录的真实浏览器,复用登录状态,完全绕过所有自动化检测。
原理
- 用户在普通浏览器中登录网站
- 使用 Chrome 的远程调试模式启动浏览器
- 通过 Chrome DevTools MCP 连接到该浏览器
- 所有检测都认为这是真实用户操作
实施步骤
步骤 1:启动带调试端口的 Chrome
1 2 3 4 5 6 7
| /Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome \ --remote-debugging-port=9222 \ --user-data-dir="/tmp/chrome-debug-profile"
chrome.exe --remote-debugging-port=9222 --user-data-dir="C:\temp\chrome-debug"
|
步骤 2:配置 Chrome DevTools MCP
方式一:全局配置(所有项目适用)
在 Claude Code 的 ~/.claude.json 中添加:
1 2 3 4 5 6 7 8
| { "mcpServers": { "chrome-devtools": { "command": "npx", "args": ["-y", "chrome-devtools-mcp@latest", "--browser-url=http://127.0.0.1:9222"] } } }
|
方式二:OpenClaw 项目本地配置
在 OpenClaw 项目的 .claude/settings.local.json 中配置权限:
1 2 3 4 5 6 7 8 9 10 11 12
| { "permissions": { "allow": [ "Bash(/Applications/Google\\ Chrome.app/Contents/MacOS/Google\\ Chrome:*)", "mcp__chrome-devtools__browser_navigate", "mcp__chrome-devtools__browser_snapshot", "mcp__chrome-devtools__browser_click", "mcp__chrome-devtools__browser_type", "mcp__chrome-devtools__browser_screenshot" ] } }
|
MCP 服务器安装与配置流程(OpenClaw 专用)
由于 OpenClaw 项目使用 Playwright MCP 进行浏览器操作,如需切换到 Chrome DevTools MCP,按以下步骤:
- 安装 Chrome DevTools MCP
1 2 3
| npm install -g chrome-devtools-mcp
npx -y chrome-devtools-mcp@latest --version
|
- 配置 MCP 服务器连接方式
Chrome DevTools MCP 支持两种连接方式:
| 方式 |
说明 |
适用场景 |
--autoConnect |
自动连接到本机已运行的 Chrome |
Chrome 144+ 已开启远程调试 |
--browser-url |
连接到指定调试端口 |
手动启动调试 Chrome |
- 在 OpenClaw 项目中启用 Chrome DevTools MCP
在 ~/.claude.json(全局配置)中添加:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| { "mcpServers": { "playwright": { "command": "npx", "args": ["-y", "playwright-mcp@latest"] }, "chrome-devtools": { "command": "npx", "args": [ "-y", "chrome-devtools-mcp@latest", "--browser-url=http://127.0.0.1:9222", "--no-usage-statistics" ] } } }
|
- 配置 OpenClaw 项目权限
在 .claude/settings.local.json 中添加:
1 2 3 4 5 6 7 8 9 10 11 12 13
| { "permissions": { "allow": [ "mcp__chrome-devtools__browser_navigate", "mcp__chrome-devtools__browser_snapshot", "mcp__chrome-devtools__browser_click", "mcp__chrome-devtools__browser_type", "mcp__chrome-devtools__browser_screenshot", "mcp__chrome-devtools__browser_evaluate", "mcp__chrome-devtools__browser_console_messages" ] } }
|
步骤 3:用户先手动登录目标网站
在步骤 1 启动的 Chrome 中访问目标网站,手动完成登录和任何安全验证。
步骤 4:使用 MCP 工具操作浏览器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| await browser_navigate({ url: 'https://www.zhipin.com/web/geek/jobs' });
await browser_snapshot();
await browser_click({ element: 'Job list item', ref: 'xxx' });
await browser_type({ element: 'Search input', ref: 'yyy', text: 'software engineer' });
|
四、OpenClaw 项目集成
4.1 架构设计
1 2 3 4 5 6 7 8 9
| ┌─────────────────────────────────────────────────────────────┐ │ Claude Code │ ├─────────────────────────────────────────────────────────────┤ │ Chrome DevTools MCP │ ├─────────────────────────────────────────────────────────────┤ │ CDP (Chrome Remote Debugging) │ ├─────────────────────────────────────────────────────────────┤ │ 真实 Chrome (用户已登录) │ └─────────────────────────────────────────────────────────────┘
|
4.2 代码实现示例
使用 CDP 直接连接:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| const CDP = require('chrome-remote-interface');
async function operateBrowser() { const client = await CDP({ port: 9222 }); const { Page, Runtime } = client;
await Page.enable();
await Page.navigate({ url: 'https://www.zhipin.com/web/geek/jobs' }); await Page.loadEventFired();
const { result } = await Runtime.evaluate({ expression: `document.title`, returnByValue: true });
console.log('Page title:', result.value);
await client.close(); }
|
4.3 关键优势
| 特性 |
Puppeteer |
Chrome DevTools MCP |
| 登录状态复用 |
困难 |
简单 |
| 自动化检测绕过 |
部分成功 |
完全绕过 |
| IP 验证触发 |
高 |
低 |
| 设置复杂度 |
高 |
低 |
| 稳定性 |
依赖网站策略 |
依赖真实浏览器 |
五、调试技巧
5.1 检测网站使用了哪些检测方法
在页面控制台执行:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| console.log('webdriver in navigator:', 'webdriver' in navigator); console.log('navigator.webdriver:', navigator.webdriver);
console.log('cdc_ variables:', Object.keys(window).filter(k => k.startsWith('cdc_')));
console.log('plugins:', navigator.plugins.length); console.log('languages:', navigator.languages);
const canvas = document.createElement('canvas'); const gl = canvas.getContext('webgl'); console.log('WebGL renderer:', gl ? gl.getParameter(gl.RENDERER) : 'none');
|
5.2 使用 Playwright MCP 进行调试
配置 Playwright MCP 工具可以直接检查页面状态:
1 2 3 4 5 6 7 8
| await browser_snapshot();
await browser_console_messages({ level: 'error' });
await browser_network_requests({ includeStatic: false });
|
六、注意事项
6.1 安全考虑
- 远程调试端口:仅在本地开发环境中使用,不要暴露到公网
- 用户数据目录:使用独立的调试配置文件,避免与正常浏览器冲突
- 登录状态:妥善保管登录会话,不要在不受信任的环境中共享
6.2 局限性
- 需要用户预先在浏览器中登录
- 如果网站检测 IP 变化(如 VPN/代理),仍可能触发验证
- 多设备/多地点访问可能触发安全警报
6.3 替代方案
如果 Chrome DevTools MCP 不可用,可以考虑:
- Playwright with stealth plugin:使用
puppeteer-extra-plugin-stealth
- Playwright:更多社区支持和更好的反检测插件
- Selenium:老牌方案,但同样容易被检测
七、总结
对于有强反自动化检测的网站(如 Boss直聘),推荐使用 Chrome DevTools MCP + 真实浏览器会话 的方案:
- 优势:完全绕过自动化检测,复用登录状态,设置简单
- 前提:用户需要在调试浏览器中预先登录目标网站
- 适用:需要长期稳定运行的自动化任务
对于无反自动化检测的网站,传统的 Puppeteer/Playwright 方案仍然有效且更轻量。
八、参考资料