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. 01rebrowser-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/ランタイムを認識するエンタープライズ向けボット管理システムを確実に回避できるわけではありません。測定結果については「Detection Coverage」をご覧ください。

許可された用途に限ります。 これは、所有しているサイト、またはテストを許可されているサイトでの QA、アクセシビリティテスト、調査を目的としています。各サイトの利用規約、robots.txt、適用される法律を遵守してください。ペイウォールの回避、レート制限の悪用、またはサイトが明示した意向に反するスクレイピングには使用しないでください。

検出を回避する方法(およびそのレイヤー)

回避は1つではなく、3つのレイヤーによって実現されます。大部分を担うのは手書きの JS ではなく、実際のブラウザーです。

検出ポイント標準の Playwright(ヘッドレス)回避するもの
CDP/Runtime.enable の漏えい存在する(ヘッドレスの兆候)rebrowser + REBROWSER_PATCHES_RUNTIME_FIX_MODE(自動設定)
window.__pwInitScripts(isPlaywright)存在するアーティファクトの除去(初期化スクリプトがページ遷移のたびに削除)
navigator.webdrivertruerebrowser(false を返します。削除はしていません。undefined 自体が検出の手がかりになります)
WebGL レンダラーSwiftShader(ソフトウェア)channel:'chrome' + ヘッド付きモード(実際の GPU)
ユーザーエージェント"HeadlessChrome" を含むchannel:'chrome'(実際の Chrome UA)。JS による上書きなし
Canvas フィンガープリントソフトウェアレンダリングの兆候ヘッド付きの実際の Chrome(本物の GPU キャンバス)。JS による細工なし
navigator.plugins空の配列ヘッド付きの実際の Chrome(本物の PluginArray)。JS による偽装なし
navigator.languages['en-US'] のみlocale オプション(ネイティブでワーカーと整合し、JS ゲッターなし)

なぜ手書きの JS がこれほど少ないのですか? v2.1/v2.2 では、以前の偽 PluginArray、キャンバスノイズ、固定値の hardwareConcurrency、Permissions の上書き、webdriver の削除、navigator.languages ゲッターをすべて削除しました。どれも検出可能な不整合(独自プロパティによる兆候、ワーカーとの不一致、undefined の webdriver、Illegal invocation クラッシュ)を生み出していたためです。v2.2 で有効な対策は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)が対象とするのは、次の2つの対策だけです。

対策理由
window.__pwInitScripts / __playwright* を削除する(初期化スクリプト、すべてのナビゲーション)検出ツールが利用する、確定的な isPlaywright のシグネチャを取り除きます
REBROWSER_PATCHES_RUNTIME_FIX_MODE=addBinding(インポート前に自動設定)CDP の Runtime.enable によるヘッドレスの漏えいを隠します

navigator には何も手を加えません。その他はすべて実際のブラウザー(channel:'chrome' + headed)に任せています。これにより、本物の User-Agent、WebGL/GPU レンダラー、canvas フィンガープリント、PluginArray、一貫性のある権限・ハードウェア値、そして(locale オプションを介した)ネイティブワーカーと一致する navigator.languages + Accept-Language が得られます。

v2.1/v2.2 で削除(実際の環境と値の一貫性がなく、いずれも総合的に悪影響があったため):偽の navigator.plugins、canvas getImageData のノイズ、固定値の hardwareConcurrency/deviceMemory、outerWidth/Height のオフセット、権限の上書き(Illegal invocation でクラッシュ)、navigator.webdriver の削除(undefined になり、かえって手掛かりになる)、navigator.languages ゲッター(独自プロパティとワーカー不一致の手掛かりになる)。

起動引数:--disable-blink-features=AutomationControlled。--no-sandbox はオプトイン({ noSandbox: true })です。セキュリティリスクであると同時に自動化のシグナルでもあるため、デフォルトでは無効です。

負荷の高い SPA(TikTok/IG/FB)では、addBinding モードで致命的ではない [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 の一時ディレクトリ(os.tmpdir())に保存されます。macOS/Linux では /tmp、Windows では %TEMP% です。

検出範囲(2026-06-10 測定、macOS の headed 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✅ ヘッドレス 0% / ステルス 0%あいまいな「38% like headless」は検出ではありません
nowsecure.nl(Cloudflare Turnstile)⚠️ インタラクティブなチャレンジが表示されます動作/IP によるゲートであり、フィンガープリントのチェックではありません。自動通過しません

信頼性:繰り返し実行した 9/9 回で問題なし(__pwInitScripts の削除はすべてのナビゲーションで維持されました)。

v2.2 がこれを実現する仕組み(そして解決できない唯一のこと)

createStealthBrowser() に組み込まれた、2 つの対策があります。

  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 から各サイトを 1 回ずつ読み込んだ結果です。大量にアクセスすると、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 は JavaScript レベルでのみパッチを適用するため、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" を指定してください

コメント