目录

一、为什么会被检测?

1. navigator.webdriver

2. Chrome 命令行标志位

3. navigator.plugins / navigator.languages / 其他指纹

4. User-Agent 不匹配

5. 屏幕分辨率/视口

二、核心反检测配置(已验证有效)

三、参数详解

3.2 add_init_script()

3.3 set_viewport_size()

3.4 对比:new_context() vs new_page()

四、扩展反检测手段

4.1 覆盖更多 navigator 属性

4.2 使用 channel="chrome" 系统已安装浏览器

4.3 设置真实时区/语言/地理位置

4.4 禁用不必要的资源加载(提高速度)

五、验证是否被检测

5.1 在线检测工具

5.2 手动验证

5.3 常用调试代码

六、注意事项

1. 自定义 User-Agent 要谨慎

2. 反检测配置只解决"身份"问题

3. 不同网站检测方式不同

4. 定期更新 Playwright 版本


一、为什么会被检测?

网站通过以下维度判断是否为自动化工具:

1. navigator.webdriver

// Playwright 默认返回 true
navigator.webdriver  // → true  (表示由自动化工具控制)

// 真实浏览器返回 undefined 或 false
navigator.webdriver  // → undefined

这是最核心、最容易被查的属性。几乎所有反自动化检测网站都会查这个。

2. Chrome 命令行标志位

Playwright 启动的 Chrome 进程会携带自动化相关的命令行参数:

--enable-automation           # ⚠️ 标志性参数
--remote-debugging-port=...   # ⚠️ 调试端口
--remote-allow-origins=*      # ⚠️ 允许远程连接

--disable-blink-features=AutomationControlled 的作用就是关闭这些暴露标志位的 Blink 特性。

3. navigator.plugins / navigator.languages / 其他指纹

Playwright 默认的指纹和真实浏览器有细微差异:

  • navigator.plugins.length 可能不符合预期
  • navigator.languages 缺省值可能暴露
  • chrome.runtime 相关对象缺失

4. User-Agent 不匹配

Playwright 的默认 UA 不包含具体 Chrome 版本号,或版本号与实际不一致。

5. 屏幕分辨率/视口

默认视口(1280×720)是常见的自动化工具特征。


二、核心反检测配置(已验证有效)

以下配置经过 Baidu 实战验证,仅需 11 行代码即可绕过百度人机验证:

browser = await p.chromium.launch(
    headless=False,
    args=['--disable-blink-features=AutomationControlled']   # 去掉自动化标志位
)
page = await browser.new_page()
await page.set_viewport_size({'width': 1920, 'height': 1080})  # 设置真实分辨率
await page.add_init_script("""                                   # 覆盖 navigator.webdriver
    Object.defineProperty(navigator, 'webdriver', {
        get: () => undefined
    });
""")
await page.goto("https://www.baidu.com")

这 3 项措施分别解决:

配置解决的问题验证结论
--disable-blink-features=AutomationControlled隐藏 Chrome 自动化命令行标志必选 ✅
add_init_script() 覆盖 navigator.webdriver让 JS 查不到自动化属性必选 ✅
set_viewport_size()设置真实分辨率,减小指纹差异推荐 ✅

三、参数详解

作用:禁止 Blink 引擎暴露自动化控制相关的特性。

Playwright 启动 Chrome 时会默认注入 <body dom-automation="true"> 等标记和命令行参数。这个 flag 让 Blink 不暴露这些自动化特征。

用法:

browser = await p.chromium.launch(
    headless=False,
    args=[
        '--disable-blink-features=AutomationControlled',
        # 可以叠加其他 arg,比如:
        # '--no-sandbox',                  # Linux Docker 环境
        # '--disable-web-security',         # 禁用跨域(仅供测试)
    ]
)

注意:这是一个启动参数(传递给 Chrome 进程),不是 Playwright API,要放在 launch() 的 args 列表里。


3.2 add_init_script()

作用:在页面加载任何脚本之前注入自定义 JavaScript,常用于覆盖浏览器指纹属性。

核心用法——隐藏 navigator.webdriver:

await page.add_init_script("""
    Object.defineProperty(navigator, 'webdriver', {
        get: () => undefined
    });
""")

原理:

  • Object.defineProperty 重新定义了 navigator.webdriver 的 getter
  • 任何 JS 读取 navigator.webdriver 都得到 undefined,不返回 true
  • 这个脚本在页面本身的 JS 之前执行,所以页面 JS 无法发现被篡改

可以注入多个初始化脚本:

await page.add_init_script("""
    // 隐藏 webdriver
    Object.defineProperty(navigator, 'webdriver', {
        get: () => undefined
    });
    
    // 模拟 Chrome 运行时(绕过部分插件检测)
    window.chrome = {
        runtime: {}
    };
    
    // 覆盖权限查询(让权限 API 返回 prompt 而非 denied)
    const originalQuery = window.navigator.permissions.query;
    window.navigator.permissions.query = (params) => (
        params.name === 'notifications' ?
            Promise.resolve({state: 'prompt'}) :
            originalQuery(params)
    );
""")

3.3 set_viewport_size()

作用:设置页面视口大小,模拟真实设备分辨率。

await page.set_viewport_size({'width': 1920, 'height': 1080})

常见分辨率:

设备分辨率适用场景
台式机 27"1920×1080默认办公/家用
笔记本 14"1366×768常见笔记本
笔记本 16"1920×1080主流笔记本
2K 显示器2560×1440高分辨率
4K 显示器3840×2160超高清(需缩放)

注意:若页面中 #chat-input-area 等组件是响应式的,不同视口可能导致布局变化。建议用自己电脑的真实分辨率。


3.4 对比:new_context() vs new_page()

方法上下文User-Agent适用场景
browser.new_page()默认浏览器上下文真实 Playwright Chrome UA✅ 推荐,UA 最真实
browser.new_context()新建隔离上下文可自定义⚠️ 自定义 UA 可能导致页面版本不同

实战教训:使用 browser.new_context(user_agent='Chrome/120...') 自定义 UA,百度返回了不含 AI 组件的旧版页面。改为 browser.new_page() 后问题解决。


四、扩展反检测手段

以下手段在更严格的网站(如淘宝、银行网站)可能需要,当前 Baidu 场景不需要。

4.1 覆盖更多 navigator 属性

await page.add_init_script("""
    // 隐藏 webdriver
    Object.defineProperty(navigator, 'webdriver', {
        get: () => undefined
    });
    
    // 覆盖 plugins 长度(部分网站检查)
    Object.defineProperty(navigator, 'plugins', {
        get: () => [1, 2, 3, 4, 5]
    });
    
    // 覆盖 languages(部分网站检查)
    Object.defineProperty(navigator, 'languages', {
        get: () => ['zh-CN', 'zh', 'en']
    });
""")

4.2 使用 channel="chrome" 系统已安装浏览器

browser = await p.chromium.launch(
    channel="chrome",  # 使用系统已安装的 Chrome,而非 Playwright 自带的 Chromium
    headless=False,
    args=['--disable-blink-features=AutomationControlled']
)

优势:系统 Chrome 的指纹更真实(有登录态、扩展、历史记录等)。
前提:电脑必须已安装 Chrome 浏览器。

4.3 设置真实时区/语言/地理位置

context = await browser.new_context(
    locale='zh-CN',
    timezone_id='Asia/Shanghai',
    geolocation={'latitude': 39.9042, 'longitude': 116.4074},
    permissions=['geolocation'],
)
page = await context.new_page()

4.4 禁用不必要的资源加载(提高速度)

# 拦截图片/字体等资源,提高页面的加载速度和被检测的概率减低
await page.route("**/*", lambda route: route.abort() 
    if route.request.resource_type in ["image", "font", "media"] 
    else route.continue_())

五、验证是否被检测

5.1 在线检测工具

运行 Playwright 后,打开浏览器访问以下网站检测指纹:

工具网址说明
BrowserScanhttps://www.browserscan.net全面检测 WebDriver、指纹等
sannysofthttps://bot.sannysoft.com检测自动化特征
Cloudflare随时随地连接、保护和构建 | CloudflareCloudflare 五秒盾测试
fingerprintjsFingerprintJS Demo浏览器指纹检测

5.2 手动验证

在 Playwright 的页面中执行 JS 检查关键属性:

# 检查 navigator.webdriver
result = await page.evaluate("navigator.webdriver")
print(f"navigator.webdriver = {result}")  # 期望: undefined

# 检查 plugins
plugins_len = await page.evaluate("navigator.plugins.length")
print(f"plugins 数量: {plugins_len}")

# 检查 window.chrome
has_chrome = await page.evaluate("'chrome' in window")
print(f"有 chrome 对象: {has_chrome}")

5.3 常用调试代码

# 一行代码查所有关键指纹
fingerprint = await page.evaluate("""() => ({
    webdriver: navigator.webdriver,
    plugins: navigator.plugins.length,
    languages: navigator.languages,
    hardwareConcurrency: navigator.hardwareConcurrency,
    deviceMemory: navigator.deviceMemory,
    userAgent: navigator.userAgent,
    viewport: {w: window.innerWidth, h: window.innerHeight}
})""")
print(fingerprint)

六、注意事项

1. 自定义 User-Agent 要谨慎

# ❌ 可能触发不同页面版本
context = await browser.new_context(
    user_agent='Mozilla/5.0 ... Chrome/120 ...'
)

# ✅ 用默认的,Playwright 自动匹配真实版本
page = await browser.new_page()

2. 反检测配置只解决"身份"问题

反检测让网站"认为你是真人浏览器",但你的操作方式(如瞬移点击、批量提交)仍然可能导致被限流或封号。

3. 不同网站检测方式不同

  • 百度:主要查 navigator.webdriver 和自动化标志位 → 本文配置足够
  • 淘宝/京东:可能有更复杂的指纹检测,可能需要额外手段
  • Cloudflare:查 TLS 指纹 + JS 执行环境,可能需要 channel="chrome"

4. 定期更新 Playwright 版本

反检测技术是攻防对抗——Playwright 更新可能会改变浏览器启动行为,网站检测手段也会升级。保持版本更新有助于应对。

Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐