Home
Softono
playwright-bot-bypass

playwright-bot-bypass

Open source MIT JavaScript
148
Stars
11
Forks
1
Issues
1
Watchers
4 weeks
Last Commit

About playwright-bot-bypass

Claude Code skill to bypass bot detection (Google CAPTCHA, etc.)

Platforms

Web Self-hosted

Languages

JavaScript

Links

playwright-bot-bypass v2.2

A Claude Code skill that wires existing stealth tools β€” rebrowser-playwright, real headed Chrome, and undetected-chromedriver β€” into a single, agent-ready bundle.

Authorized use only. For QA, accessibility testing, and research on sites you own or are permitted to test. Respect each site's Terms of Service, robots.txt, and applicable law.

What this skill is (and isn't)

It is a packaging + integration layer. The hard stealth work lives in upstream projects (see Credits). What this skill adds:

  • 🧩 A one-import factory β€” createStealthBrowser() returns a ready { browser, page } so an agent doesn't have to rediscover the right combination of channel:'chrome' + headed + rebrowser env var + init script.
  • 🎯 A verified recipe β€” which knobs to set and, just as important, which fakes NOT to add. Measured against 8 detectors: the artifact-strip + Runtime-fix pass; the old hand-rolled navigator fakes actively hurt (see How It Works).
  • πŸ“Š Reproducible proof β€” A/B screenshots + a measured detection-coverage matrix, with honest limits.
  • πŸ€– Agent docs β€” SKILL.md so Claude Code can use and reason about it directly.

It is NOT a new stealth engine. It does not author rebrowser-playwright, undetected-chromedriver, or the underlying detection research β€” it stitches them together and tunes the result.

Installation

npx skills add greekr4/playwright-bot-bypass

What you get

  • βœ… Passes fingerprint + automation-framework detectors (sannysoft, rebrowser-detector, deviceandbrowserinfo, browserscan, iphey, creepjs) β€” measured, 9/9 reproducible
  • βœ… Google search without triggering CAPTCHA; public Reddit/YouTube/TikTok/X loads with no bot challenge
  • βœ… Real GPU fingerprint, real Chrome UA, genuine PluginArray β€” from real headed Chrome, not faked in JS
  • βœ… One-import factory + human-like helpers (mouse movement, typing delays), cookie persistence, proxy support
  • βœ… Node.js (rebrowser-playwright) and Python (undetected-chromedriver) paths

A/B: plain Playwright vs this skill

Measured 2026-06-10 (macOS, Apple Silicon). A = default playwright (headless bundled Chromium, no stealth). B = this skill via createStealthBrowser() (headed real Chrome + rebrowser Runtime-fix + Playwright-artifact strip). Same three detectors, same machine.

deviceandbrowserinfo.com β€” "Are you a bot?"

A Β· plain Playwright B Β· this skill
bot human
❌ "You are a bot!" (isBot: true) βœ… "You are human!" (isBot: false)

bot-detector.rebrowser.net β€” CDP/automation tests (rebrowser's own detector)

A Β· plain Playwright B Β· this skill
reds green
πŸ”΄ navigatorWebdriver (= true) 🟒 all green β€” webdriver false, no __pwInitScripts, no Runtime leak

bot.sannysoft.com β€” fingerprint suite

A Β· plain Playwright B Β· this skill
detected passed
Red rows: WebDriver / Chrome / UA = HeadlessChrome / WebGL SwiftShader All green β€” real Chrome UA, Apple M2 WebGL, webdriver false

Honest scope: these are fingerprint + automation-framework detectors, and B passes them cleanly and repeatably (9/9 runs). This does not mean every site is bypassed β€” IP reputation, behavioral analysis, and login walls (Instagram/Facebook/LinkedIn) are untouched. See SKILL.md β†’ Detection Coverage for the full measured matrix and the one residual leak (__playwright_builtins__) that no current rebrowser version can strip.

How It Works (3 layers)

The skill's job is to pick the right layers and let them do the work β€” most evasion is the real browser and the upstream library, not hand-written JS. The skill's own contribution is the integration: the artifact-strip init script, auto-setting the rebrowser env var, and removing the fakes that backfire.

Layer Handles
rebrowser-playwright + Runtime-fix (REBROWSER_PATCHES_RUNTIME_FIX_MODE, auto-set) CDP Runtime.enable headless leak; reports webdriver: false
channel:'chrome' + headed real UA, WebGL/GPU, canvas fingerprint, PluginArray, hardware/permission consistency, native navigator.languages via locale
artifact strip (one init script) deletes window.__pwInitScripts / __playwright* (the isPlaywright signature) every navigation

v2.2 touches nothing on navigator. Removed across v2.1/v2.2 (each faked values inconsistently β†’ net-negative): fake navigator.plugins, canvas noise, hardcoded hardwareConcurrency/deviceMemory, outerWidth/Height offset, the permissions override (Illegal invocation crash), the webdriver delete (made it undefined β€” a tell), and the navigator.languages getter (own-property + worker-mismatch tells).

Launch arg: --disable-blink-features=AutomationControlled. --no-sandbox is opt-in ({ noSandbox: true }) β€” a security risk and a bot signal, off by default. Real Chrome via channel: 'chrome'.

Real community sites (single logged-out load, residential IP)

Site Result
Reddit, YouTube, Pinterest, Threads, X, Quora, TikTok 🟒 content fully loaded β€” no bot challenge / CAPTCHA
Instagram, Facebook, LinkedIn 🟑 content behind the normal logged-out login modal β€” not a bot block / checkpoint / 999

None returned a bot challenge β€” even IG/FB/LinkedIn served the standard human logged-out experience. Caveat: one load each on a clean residential IP; at volume those three enforce datr/999/rate-limits (IP & account problems this skill does not solve).

Quick Start

Node.js (Recommended)

npm init -y && npm install rebrowser-playwright

Using the template (recommended)

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

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

try {
  await page.goto('https://example.com');
  await simulateMouseMovement(page);  // Natural mouse movement
  await humanType(page, 'input', 'query');  // Human-like typing
  await humanDelay(300, 800);
} finally {
  await browser.close();
}

Template options

createStealthBrowser({
  headless: false,              // Required for stealth (default)
  viewport: { width: 1280, height: 800 },
  locale: 'ko-KR',             // Browser locale (sets navigator.languages + Accept-Language)
  storageState: './session.json',  // Cookie persistence
  proxy: { server: 'http://proxy:8080' },  // Proxy support
  noSandbox: false             // Opt-in --no-sandbox (Linux root/CI only)
});

Manual setup

// Runtime-fix must be set before importing rebrowser-playwright.
process.env.REBROWSER_PATCHES_RUNTIME_FIX_MODE ??= 'addBinding';
const { chromium } = await import('rebrowser-playwright');

const browser = await chromium.launch({
  headless: false,
  channel: 'chrome',
  args: ['--disable-blink-features=AutomationControlled']  // --no-sandbox is opt-in; it's a bot signal
});

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

await context.addInitScript(() => {
  // strip Playwright's main-world signature; touch nothing on navigator
  for (const k of Object.getOwnPropertyNames(window)) {
    if (/^__pw|pwInitScripts|playwright/i.test(k)) { try { delete window[k]; } catch {} }
  }
});

const page = await context.newPage();
try {
  await page.goto('https://google.com');
} finally {
  await browser.close();
}

Python

pip install undetected-chromedriver
import undetected_chromedriver as uc

driver = uc.Chrome()  # auto-detects Chrome version
driver.get('https://google.com')

Python playwright-stealth only patches at JS level β€” WebGL still shows SwiftShader. Use undetected-chromedriver instead.

Test Results

Environment bot.sannysoft.com Google Search bluer.co.kr
Standard Playwright Detected CAPTCHA 403
This skill (rebrowser + headed Chrome) Pass Works 200
playwright-stealth (Python) Pass CAPTCHA -
undetected-chromedriver (Python path) Pass Works -

Scripts Included

skills/playwright-bot-bypass/
  scripts/
    stealth-template.mjs      # Reusable stealth factory (all examples import this)
    bot-detection-test.mjs     # Verify bypass at bot.sannysoft.com
  examples/
    stealth-google-search.mjs  # Google search without CAPTCHA
    ab-test.mjs                # Side-by-side detected vs stealth
    stealth-twitter-scrape.mjs # Twitter/X profile scraping
  package.json                 # Dependencies (type: module)
  marketplace.json
  SKILL.md                     # Full documentation for Claude Code agents

Requirements

  • Node.js 18+ (ESM / .mjs)
  • Google Chrome installed (not just Chromium)
  • Headed mode (display required β€” headless: false)

Troubleshooting

Problem Fix
ERR_MODULE_NOT_FOUND Run npm install rebrowser-playwright in your script directory
Browser not opening Verify Chrome: /Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --version
WebGL shows SwiftShader You're effectively headless / GPU-less. Run headed (headless: false) with channel: 'chrome' on a machine with a real GPU β€” SwiftShader is the software fallback, not an import issue
Still getting detected Add simulateMouseMovement() and humanDelay() between actions
Process hangs Ensure browser.close() is in a finally block

Credits

This skill is glue + tuning on top of other people's work. All the heavy lifting belongs to:

What's original here is the integration: the createStealthBrowser() factory, the verified v2.2 recipe (the __pwInitScripts strip + auto Runtime-fix, and the decision to remove counter-productive navigator fakes), the measured A/B + coverage matrix, and the agent-facing SKILL.md.

License

MIT