0%

浏览器自动化检测解决方案

浏览器自动化检测解决方案

概述

本文档记录了针对网站反自动化检测的完整解决方案,适用于 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
// Puppeteer 注入的代码
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 验证仍可能触发。

3.3 终极方案:Chrome DevTools MCP + 真实登录会话 (推荐)

核心思路:使用用户已登录的真实浏览器,复用登录状态,完全绕过所有自动化检测。

原理

  1. 用户在普通浏览器中登录网站
  2. 使用 Chrome 的远程调试模式启动浏览器
  3. 通过 Chrome DevTools MCP 连接到该浏览器
  4. 所有检测都认为这是真实用户操作

实施步骤

步骤 1:启动带调试端口的 Chrome

1
2
3
4
5
6
7
# macOS
/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome \
--remote-debugging-port=9222 \
--user-data-dir="/tmp/chrome-debug-profile"

# Windows
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,按以下步骤:

  1. 安装 Chrome DevTools MCP
1
2
3
npm install -g chrome-devtools-mcp
# 或
npx -y chrome-devtools-mcp@latest --version
  1. 配置 MCP 服务器连接方式

Chrome DevTools MCP 支持两种连接方式:

方式 说明 适用场景
--autoConnect 自动连接到本机已运行的 Chrome Chrome 144+ 已开启远程调试
--browser-url 连接到指定调试端口 手动启动调试 Chrome
  1. 在 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"
]
}
}
}
  1. 配置 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();

// 执行 JS
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
// 检测 webdriver 属性
console.log('webdriver in navigator:', 'webdriver' in navigator);
console.log('navigator.webdriver:', navigator.webdriver);

// 检测 CDP 变量
console.log('cdc_ variables:', Object.keys(window).filter(k => k.startsWith('cdc_')));

// 检测 headless 特征
console.log('plugins:', navigator.plugins.length);
console.log('languages:', navigator.languages);

// 检测 WebGL
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 不可用,可以考虑:

  1. Playwright with stealth plugin:使用 puppeteer-extra-plugin-stealth
  2. Playwright:更多社区支持和更好的反检测插件
  3. Selenium:老牌方案,但同样容易被检测

七、总结

对于有强反自动化检测的网站(如 Boss直聘),推荐使用 Chrome DevTools MCP + 真实浏览器会话 的方案:

  1. 优势:完全绕过自动化检测,复用登录状态,设置简单
  2. 前提:用户需要在调试浏览器中预先登录目标网站
  3. 适用:需要长期稳定运行的自动化任务

对于无反自动化检测的网站,传统的 Puppeteer/Playwright 方案仍然有效且更轻量。


八、参考资料