mcpField
P
playwright-bot-bypass

playwright-bot-bypass

github.com/greekr4开发208774 次安装9 周前更新
代码仓库

关于 playwright-bot-bypass

Playwright Bot Bypass 是用于获准测试的浏览器自动化技能,借助 rebrowser-playwright 和有头模式下的真实 Chrome 减少部分自动化检测信号。面向网站所有者的 QA、无障碍测试和研究;不保证绕过行为或 IP 检测,也不自动通过 CAPTCHA。

主要功能

  1. 01基于 rebrowser-playwright
  2. 02使用有头真实 Chrome
  3. 03移除部分 Playwright 标记
  4. 04提供浏览器工厂模板
  5. 05包含检测测试脚本

适用场景

  1. 01对自有网站进行自动化 QA
  2. 02测试网页无障碍表现
  3. 03研究浏览器自动化检测

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/greekr4/playwright-bot-bypass --skill playwright-bot-bypass

安装后在 Claude Code 中输入/playwright-bot-bypass确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

.gitignore
package-lock.json
package.json
examples/
ab-test.mjs
stealth-google-search.mjs
stealth-twitter-scrape.mjs
scripts/
bot-detection-test.mjs
stealth-template.mjs

详细介绍

Playwright Bot Bypass

借助 rebrowser-playwright 和真实的有头模式 Chrome 降低被检测为机器人的风险。可通过指纹检测网站(bot.sannysoft.com、areyouheadless)的检查,并避免在 Google 上触发 CAPTCHA。不保证能够绕过能感知 CDP/运行时的企业级机器人管理系统——实测结果请参阅“检测覆盖范围”。

仅限授权用途。 本工具用于对你拥有或获准测试的网站进行 QA、无障碍测试和研究。请遵守各网站的服务条款、robots.txt 和适用法律。请勿使用本工具绕过付费墙、滥用速率限制,或违背网站明确意愿进行抓取。

如何绕过检测(以及各层的作用)

规避检测依赖三层措施,而非单一手段——其中大部分来自真实浏览器,而非手写的 JS:

检测点标准 Playwright(无头模式)绕过方式
CDP / Runtime.enable 泄漏存在(无头模式特征)rebrowser + REBROWSER_PATCHES_RUNTIME_FIX_MODE(自动设置)
window.__pwInitScripts(isPlaywright)存在清除残留(初始化脚本会在每次导航时删除它)
navigator.webdrivertruerebrowser(报告为 false;我们不会删除它——undefined 本身就是一种特征)
WebGL 渲染器SwiftShader(软件渲染)channel:'chrome' + 有头模式(真实 GPU)
User Agent包含 "HeadlessChrome"channel:'chrome'(真实 Chrome UA)——不使用 JS 覆盖
Canvas 指纹软件渲染特征有头模式下的真实 Chrome(真实 GPU canvas)——不添加 JS 干扰
navigator.plugins空数组有头模式下的真实 Chrome(真实 PluginArray)——不使用 JS 伪造
navigator.languages仅有 ['en-US']locale 选项(原生设置,与 worker 一致——不使用 JS getter)

为什么只写这么少 JS? 在 v2.1/v2.2 中,旧版的 fake-PluginArray、canvas-noise、硬编码的 hardwareConcurrency、permissions-override、删除 webdriver,以及 navigator.languages getter 均已移除——这些做法都会造成可检测的不一致(自有属性特征、worker 不匹配、webdriver 为 undefined、Illegal invocation 崩溃)。v2.2 只保留两项启用中的措施:清除 Playwright 的 __pwInitScripts 残留,并启用 rebrowser 的 Runtime-fix。其余一切都由真实且自洽的浏览器处理。伪造越少 = 一致性越高 = 越难检测。

前提条件

  • Node.js 18+,支持 ESM(.mjs 文件)
  • 已安装 Google Chrome(不只是 Chromium)
  • 必须使用有头模式(headless: false)——没有显示环境就无法隐蔽运行

验证 Chrome 是否已安装:

# macOS
/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --version
# Windows
"C:\Program Files\Google\Chrome\Application\chrome.exe" --version
# Linux
google-chrome --version

快速开始

1. 安装
npm init -y && npm install rebrowser-playwright
2. 创建 stealth-test.mjs
import os from 'node:os';
import path from 'node:path';

// Enable rebrowser's Runtime.enable fix BEFORE importing the library.
process.env.REBROWSER_PATCHES_RUNTIME_FIX_MODE ??= 'addBinding';
const { chromium } = await import('rebrowser-playwright');

const browser = await chromium.launch({
  headless: false,                                  // headed = real GPU/canvas
  channel: 'chrome',                                // real Chrome = real UA/WebGL/plugins
  args: ['--disable-blink-features=AutomationControlled']
});

// `locale` sets navigator.languages + Accept-Language natively & consistently.
const context = await browser.newContext({ locale: 'ko-KR' });

// The ONLY init script: strip Playwright's main-world signature. Touch NOTHING
// on navigator — the real browser's values are already genuine & consistent.
await context.addInitScript(() => {
  for (const k of Object.getOwnPropertyNames(window)) {
    if (/^__pw|pwInitScripts|playwright/i.test(k)) {
      try { delete window[k]; } catch {}
    }
  }
  if (!window.chrome) window.chrome = {};
});

const page = await context.newPage();

try {
  await page.goto('https://bot.sannysoft.com', { waitUntil: 'networkidle' });
  const out = path.join(os.tmpdir(), 'stealth-test.png');
  await page.screenshot({ path: out });
  console.log(`Screenshot saved: ${out}`);
} finally {
  await browser.close();
}
3. 运行
node stealth-test.mjs

使用模板(推荐)

scripts/stealth-template.mjs 提供了一个可复用的工厂函数,其中已预先应用所有补丁:

import { createStealthBrowser, humanDelay, humanType, simulateMouseMovement } from './scripts/stealth-template.mjs';

const { browser, page } = await createStealthBrowser();

try {
  await page.goto('https://example.com');

  // Human-like mouse movement (avoids Cloudflare Turnstile)
  await simulateMouseMovement(page);

  // Human-like typing instead of instant fill
  await humanType(page, 'input[name="q"]', 'search query');
  await humanDelay(300, 800);
} finally {
  await browser.close();
}
模板选项
const { browser, context, page } = await createStealthBrowser({
  headless: false,             // Required for stealth (default)
  viewport: { width: 1280, height: 800 },  // Default
  locale: 'ko-KR',            // Browser locale (default)
  userAgent: null,             // Custom UA (optional; default = real Chrome UA)
  storageState: './session.json',  // Cookie persistence (optional)
  proxy: { server: 'http://proxy:8080' },  // Proxy (optional)
  noSandbox: false             // Opt-in --no-sandbox (Linux root/CI only; it's a bot signal)
});

// Save session for reuse
import { saveSession } from './scripts/stealth-template.mjs';
await saveSession(context, './session.json');

模板的实际作用

该模板(v2.2)将生效范围严格限制为两项措施:

措施原因
移除 window.__pwInitScripts / __playwright*(初始化脚本,每次导航时执行)移除 isPlaywright 确定性特征检测器所依赖的标记
REBROWSER_PATCHES_RUNTIME_FIX_MODE=addBinding(导入前自动设置)隐藏 CDP Runtime.enable 暴露的无头浏览器特征

它对 navigator 毫不改动。其余一切都交由真实浏览器处理(channel:'chrome' + 有头模式):真实的 User-Agent、WebGL/GPU 渲染器、Canvas 指纹、PluginArray、自洽的权限/硬件值,以及(通过 locale 选项)与原生 Worker 一致的 navigator.languages + Accept-Language。

v2.1/v2.2 中移除的内容(每项都会产生负面影响,因为伪造的值与真实环境不一致):伪造的 navigator.plugins、Canvas getImageData 噪声、硬编码的 hardwareConcurrency/deviceMemory、outerWidth/Height 偏移、权限覆盖(因 Illegal invocation 而崩溃)、删除 navigator.webdriver(使其变为 undefined,反而暴露特征),以及 navigator.languages getter(会暴露自身属性 + Worker 不匹配特征)。

启动参数:--disable-blink-features=AutomationControlled。--no-sandbox 为可选启用({ noSandbox: true })——它既有安全风险,也是自动化信号,因此默认关闭。

在 addBinding 模式下,复杂的 SPA(TikTok/IG/FB)可能会输出非致命的 [rebrowser-patches] cannot get world 警告,但页面仍会加载。如有需要,可切换到 REBROWSER_PATCHES_RUNTIME_FIX_MODE=alwaysIsolated 以消除这些警告。

脚本

  • scripts/stealth-template.mjs — 可复用的隐身浏览器工厂(所有示例都从此处导入)
  • scripts/bot-detection-test.mjs — 在 bot.sannysoft.com 验证绕过效果

示例

  • examples/stealth-google-search.mjs — 无需 CAPTCHA 的 Google 搜索
  • examples/ab-test.mjs — 并排对比检测模式与隐身模式
  • examples/stealth-twitter-scrape.mjs — 抓取 Twitter/X 个人资料

注意:ab-test.mjs 同时需要 rebrowser-playwright 和 playwright:

npm install rebrowser-playwright playwright && npx playwright install chromium

所有屏幕截图都会保存到操作系统的临时目录(os.tmpdir())——macOS/Linux 上为 /tmp,Windows 上为 %TEMP%。

检测覆盖情况(测量日期:2026-06-10,macOS 有头 Chrome,v2.2)

如实报告的测试结果。v2.2 的特征清理 + Runtime 修复使所有指纹/自动化检测器均显示通过:

检测器结果备注
bot.sannysoft.com✅ 全部绿色webdriver 为 false,WebGL/UA/plugins 均为真实值
arh.antoinevastel.com/bots/areyouheadless✅ “not Chrome headless”
hmaker.github.io/selenium-detector✅ “Passing”没有 chromedriver
bot-detector.rebrowser.net✅ 0 个红色项已移除 __pwInitScripts,无 Runtime 泄露,webdriver 为 false
deviceandbrowserinfo.com/are_you_a_bot✅ “You are human!”isBot:false,isPlaywright:false
browserscan.net/bot-detection✅ “Normal”CDP 测试通过(Runtime 修复)
iphey.com✅ “Trustworthy”v2.2 之前显示为“Unreliable”
creepjs✅ 无无头浏览器特征 / 无隐身特征模糊的“38% like headless”不属于检测结果
nowsecure.nl(Cloudflare Turnstile)⚠️ 显示交互式验证行为/IP 门槛,不是指纹检查;无法自动通过

可靠性:重复运行 9/9 次均正常(__pwInitScripts 清理在每次导航中均有效)。

v2.2 如何实现这一点(以及它无法修复的一点)

通过 createStealthBrowser() 内置的两个手段:

  1. 清除特征 — 初始化脚本会在每次导航时删除 window.__pwInitScripts / __playwright*(确定性的 isPlaywright 特征)。
  2. REBROWSER_PATCHES_RUNTIME_FIX_MODE=addBinding — 在导入前自动设置;隐藏 CDP Runtime.enable 泄漏。

残留泄漏:window.__playwright_builtins__ 是另一个独立的、不可配置的 Playwright 全局变量,无法删除或重新定义。目前上述检测器都不会针对它进行检测,但未来的检测器可能会。没有任何 rebrowser 版本(你使用的是最新的 1.52.0)能将其移除——该问题已在上游 rebrowser-patches#110 跟踪,目前仍未解决。

要点:可有效应对指纹和自动化框架检测。但仍不能保证绕过基于行为/IP 的系统(Cloudflare Turnstile、DataDome、Kasada)或登录墙。要应对这些情况,请添加住宅 IP 并进行真实交互,或切换引擎——patchright(可直接替换)或 nodriver(从结构上避开整个 CDP/自动化协议类别)。

真实社区网站(未登录状态下单次加载、住宅 IP、2026-06-10)

测试 v2.2 页面加载是否会被真实网站拦截为机器人(不是判断能否登录):

网站结果
Reddit、YouTube、Pinterest、Threads、X(直接 URL)、Quora、TikTok🟢 内容完整加载——无机器人验证、无 CAPTCHA
Instagram、Facebook、LinkedIn🟡 内容框架加载,但被标准的未登录登录弹窗遮挡——不是机器人拦截 / 验证页 / HTTP 999

**关键结果:**没有任何网站返回机器人验证或强硬拦截。最“难搞”的网站(IG/FB/LinkedIn)提供的是正常的未登录用户体验(在可见内容上方显示登录弹窗),这意味着隐身模式通过了检测,被视为真实用户。**注意:**每个网站都只在干净的住宅 IP 上加载了一次。大量访问时,IG/FB/LinkedIn 会执行 datr Cookie 老化、HTTP 999 和速率限制——这些是 IP/账号问题,而非指纹问题,本技能无法解决。TikTok 的签名 API 操作(查看个人资料之外的操作)也仍需要预热过的会话。

限制

  • 需要 headless: false(带显示器的有头模式)
  • 需要安装真正的 Google Chrome(channel: 'chrome')
  • 某些网站仍可能根据行为模式进行检测——请使用 humanDelay、humanType、simulateMouseMovement
  • 不会绕过 CAPTCHA,只会避免触发 CAPTCHA
  • TLS/JA3 指纹由 channel: 'chrome' 处理(使用真正的 Chrome 二进制文件)
  • __pwInitScripts 泄漏(参见检测覆盖范围)无法在技能层面修复——这是 rebrowser-playwright 1.52.0 固有的问题

Python 支持

undetected-chromedriver(推荐)
pip install undetected-chromedriver
import undetected_chromedriver as uc

# Match your Chrome version: check chrome://version
driver = uc.Chrome()  # auto-detects version

driver.get("https://www.google.com")
search_box = driver.find_element("name", "q")
search_box.send_keys("your search query")
search_box.submit()

Python playwright-stealth 只在 JS 层面进行修补——WebGL 仍会显示 SwiftShader。请改用 undetected-chromedriver。

替代方案:从 Python 调用 Node.js
import subprocess
result = subprocess.run(['node', 'stealth-script.mjs', query], capture_output=True)

故障排除

问题修复方法
ERR_MODULE_NOT_FOUND在脚本所在目录运行 npm install rebrowser-playwright
浏览器无法打开确认已安装 Chrome(参见先决条件)
WebGL 显示 SwiftShader实际上你处于无头模式 / 没有 GPU。请在有真实 GPU 的机器上使用 channel: 'chrome' 运行有头模式(headless: false);SwiftShader 是软件回退方案,而非导入问题
仍被检测到在操作之间添加 simulateMouseMovement() 和 humanDelay()
进程挂起确保 browser.close() 位于 finally 块中
SyntaxError: await文件必须是 .mjs,或在 package.json 中设置 "type": "module"

评论

支持 Markdown