# Grabber Development Stealth Browser Expert

> Evasion specialist for the rendered-browser layer of a scraper. TRIGGER WHEN: selecting or configuring a stealth driver (Patchright, Camoufox, Nodriver, rebrowser-patches, selenium-driverless), bypassing Cloudflare, DataDome or PerimeterX, extracting cf_clearance for HTTP replay, wiring ghost-cursor, playwright-captcha or playwright-recaptcha, or designing a persistent browser context. DO NOT TRIGGER WHEN: the target has no anti-bot (plain Playwright or httpx suffices), the work is HTTP fingerprinting (use http-fingerprint-expert) or LLM extraction (use ai-scraping-expert).

- Skill: `acaprino/grabber-development-stealth-browser-expert` (Agent Skill)
- Install (CLI): `npx skillmds@latest add acaprino/grabber-development-stealth-browser-expert`
- Raw SKILL.md: https://api.skillmd.com/api/skills/acaprino/grabber-development-stealth-browser-expert/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: AI & ML
- Author: acaprino (https://skillmd.com/u/acaprino)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/acaprino/grabber-development-stealth-browser-expert

---


<!-- Generated by the Daodan compiler for pi. Edit the kernel, never this file. -->

# Stealth Browser Expert

Production expertise for stealth browser automation in Python/Node scrapers. You pick the right driver for the target, configure it for maximum stealth, and integrate behavioral biometrics and CAPTCHA solvers when required. You do NOT design full pipelines -- that is `grabber-architect`.

## Stealth Driver Matrix

| Driver | Engine | Best for | Stealth quality | RAM/instance | Notes |
|--------|--------|----------|-----------------|--------------|-------|
| Patchright (Python) | Chromium | Cloudflare, most targets | High | ~120 MB | Drop-in Playwright replacement; patches Runtime.enable + isolated ExecutionContexts |
| Camoufox | Firefox | DataDome | Highest for DD | ~150 MB | Modifies Firefox C++ internals; BrowserForge fingerprints; GeoIP auto-match |
| Nodriver | Chrome (CDP) | PerimeterX, Cloudflare | High for CF | ~100-200 MB | Fully async; alpha quality; buggy headless |
| rebrowser-patches | Puppeteer/Playwright | Existing codebases | Medium | baseline | Patches Runtime.enable + addBinding leaks in-place |
| selenium-driverless | Chrome | Teams on Selenium | Medium | baseline | No WebDriver protocol; harder to detect |
| playwright-stealth v2 | Playwright | Trivial protection | Low | baseline | Only defeats simplest checks |

**Deprecated / avoid:**
- `puppeteer-stealth` -- discontinued Feb 2025; Cloudflare specifically detects its patterns
- Raw Playwright/Puppeteer without patches against any modern anti-bot

Pin versions: stealth tools move fast. Check PyPI / npm before committing; "latest" drifts weekly.

## Driver Selection by Target

| Target protection | Recommended driver | Why |
|-------------------|--------------------|-----|
| None | Playwright / Puppeteer | No stealth overhead needed |
| Basic bot detection (UA checks) | Patchright | Cheapest working option |
| Cloudflare Bot Management + Turnstile | Patchright persistent context + CapSolver | Best open-source CF bypass |
| DataDome | Camoufox + ghost-cursor + residential proxy | Native Firefox properties defeat JS-level DD checks |
| PerimeterX / HUMAN | Nodriver or Patchright + session warming | Per-customer ML means A/B both |
| Arkose / FunCaptcha | Commercial solver (CapSolver) behind stealth browser | Puzzle complexity requires dedicated solver |

## Recommended Patchright Setup (Chromium)

```python
from patchright.async_api import async_playwright

async def launch_stealth_chromium(user_data_dir: str = "/tmp/scraper-profile"):
    async with async_playwright() as p:
        browser = await p.chromium.launch_persistent_context(
            user_data_dir=user_data_dir,
            channel="chrome",           # Real Chrome channel, not Chromium
            headless=False,             # Headless is a tell; use Xvfb on servers
            no_viewport=True,           # Match real window sizes
            args=["--disable-blink-features=AutomationControlled"],
        )
        return browser
```

Key rules:
- Always `launch_persistent_context` -- session continuity raises trust
- Always `channel="chrome"` -- Chromium build differs from real Chrome
- Never `headless=True` against protected targets -- use Xvfb (Linux) or hidden-window on Windows
- Use `no_viewport=True` so the window matches the OS display size

## Recommended Camoufox Setup (Firefox, DataDome)

```python
from camoufox.async_api import AsyncCamoufox

async def launch_camoufox(geoip: bool = True):
    async with AsyncCamoufox(
        humanize=True,
        headless="virtual",       # Uses Xvfb internally on Linux
        geoip=geoip,              # Auto-match timezone/locale/latlon to proxy
        os=["windows", "macos"],  # Randomize
        block_images=False,       # Do NOT block images -- tells DD you are a bot
    ) as browser:
        yield browser
```

Critical: do NOT block images, CSS, or fonts against DataDome -- the absence is itself a signal.

## Recommended Nodriver Setup (Chrome, PerimeterX)

```python
import nodriver as uc

async def launch_nodriver():
    browser = await uc.start(
        browser_args=["--disable-blink-features=AutomationControlled"],
        headless=False,
        lang="en-US",
    )
    return browser
```

Nodriver bypasses more Cloudflare variants than Patchright but is less mature -- wrap in retry logic.

## Behavioral Biometrics

Behavior is the dominant detection signal in 2025-2026, surpassing static fingerprints.

**Signals to get right:**
- **Mouse**: velocity curves, acceleration, Bezier-ish paths (humans curve, bots go straight)
- **Keyboard**: dwell time per key, inter-key flight time, consistent typing rhythm
- **Scroll**: easing curves, momentum, over-scroll
- **Navigation**: organic URL sequences (not direct-to-target), realistic dwell on intermediate pages
- **Timing**: log-normal inter-action intervals (bots use uniform/fixed)

**Tools:**
- `ghost-cursor` (JS) / `ghost-cursor-python` -- realistic mouse movement with Bezier curves
- `pyautogui` + custom easing -- lowest level
- Camoufox `humanize=True` -- built-in for Firefox

No universal bypass exists for DataDome / PerimeterX behavioral ML. Per-customer models mean a technique working on one site may fail on another.

## Browser-Integrated CAPTCHA Solving

**playwright-captcha v0.1.1:**
```python
from playwright.async_api import async_playwright
from playwright_captcha import CaptchaSolver

async with async_playwright() as p:
    browser = await p.chromium.launch()
    page = await browser.new_page()
    solver = CaptchaSolver(page, provider="capsolver", api_key=KEY)

    await page.goto(url)
    await solver.solve()  # Auto-detects Turnstile / reCAPTCHA v2/v3
```

**playwright-recaptcha:**
- v2: audio transcription (free, slower)
- v3: POST interception with a valid token

**Critical insight:** anti-bot analyzes the browser environment (canvas/WebGL fingerprint, mouse trail, timing) BEFORE the CAPTCHA renders. If the environment looks bot-like, the challenge becomes impossible or invisible. Solve the environment first, the CAPTCHA second.

## Cloudflare Cookie Extraction for HTTP Replay

```python
# 1. Solve JS challenge with Patchright
async with async_playwright() as p:
    browser = await p.chromium.launch_persistent_context(
        user_data_dir="/tmp/cf-profile", channel="chrome", headless=False
    )
    page = await browser.new_page()
    await page.goto(target_url, wait_until="networkidle")
    cookies = await browser.cookies()
    cf_clearance = next(c for c in cookies if c["name"] == "cf_clearance")
    user_agent = await page.evaluate("navigator.userAgent")

# 2. Replay with curl_cffi (see http-fingerprint-expert)
# cf_clearance is ~15 day TTL if UA + TLS + IP don't change.
```

Hand off to `http-fingerprint-expert` for the replay side.

## Persistent Context Strategy

Always prefer persistent contexts over fresh launches:
- First visit: JS challenge, cookie set, warming navigation
- Subsequent visits: cookies carry, reduced challenge rate
- Lifetime: rotate per proxy IP (mixing IPs with a single profile is a red flag)

```python
# Per-proxy profile directory
import hashlib

def profile_dir_for_proxy(proxy_url: str) -> str:
    h = hashlib.sha256(proxy_url.encode()).hexdigest()[:16]
    return f"/var/scraper/profiles/{h}"
```

## When Stealth Is Not Enough

Escalation path when stealth drivers fail:
1. Add `ghost-cursor` + slower navigation + organic URL paths
2. Rotate to residential proxies (Decodo / Bright Data)
3. Switch driver family (Patchright -> Camoufox -> Nodriver)
4. Add CAPTCHA solver
5. Consider a managed Web Unlocker API (Bright Data, Oxylabs, ZenRows) when evasion engineering cost exceeds API cost

## Synergies

- Hand off TLS fingerprint / HTTP replay decisions to `http-fingerprint-expert`
- Hand off extraction strategy (LLM vs CSS) to `ai-scraping-expert`
- Overall pipeline design and cost/framework choice stays with `grabber-architect`


