
Browser Automation
Harden Playwright browser automation against anti-bot detection when scraping, testing, or driving headless flows for your product.
Install
npx skills add https://github.com/alirezarezvani/claude-skills --skill browser-automationWhat is this skill?
- Maps three detection tiers: trivial (webdriver, UA, WebGL), common (viewport, plugins, timing, mouse), advanced (canvas,
- Stealth techniques centered on Playwright with defense-in-depth—no single bypass is sufficient
- Covers navigator.webdriver, HeadlessChrome UA, and SwiftShader WebGL tells
- Behavioral signals: machine-speed clicks, missing mouse paths, scroll and reading patterns
- Reference-oriented anti-detection patterns for Cloudflare-class vendors (DataDome, PerimeterX)
Adoption & trust: 539 installs on skills.sh; 17.5k GitHub stars; 3/3 security scanners passed (skills.sh audits).
Recommended Skills
Journey fit
Build/integrations is the canonical shelf because the skill is implementation knowledge for wiring Playwright stealth into apps, agents, and test harnesses—not a go-to-market activity. Integrations subphase covers third-party web UIs, scripted browsers, and E2E bridges where detection tiers and fingerprint signals matter.
Common Questions / FAQ
Is Browser Automation safe to install?
skills.sh reports 3 of 3 security scanners passed. Review the Security Audits panel on this page before installing in production.
SKILL.md
READMESKILL.md - Browser Automation
# Anti-Detection Patterns for Browser Automation This reference covers techniques to make Playwright automation less detectable by anti-bot services. These are defense-in-depth measures — no single technique is sufficient, but combining them significantly reduces detection risk. ## Detection Vectors Anti-bot systems detect automation through multiple signals. Understanding what they check helps you counter effectively. ### Tier 1: Trivial Detection (Every Site Checks These) 1. **navigator.webdriver** — Set to `true` by all automation frameworks 2. **User-Agent string** — Default headless UA contains "HeadlessChrome" 3. **WebGL renderer** — Headless Chrome reports "SwiftShader" or "Google SwiftShader" ### Tier 2: Common Detection (Most Anti-Bot Services) 4. **Viewport/screen dimensions** — Unusual sizes flag automation 5. **Plugins array** — Empty in headless mode, populated in real browsers 6. **Languages** — Missing or mismatched locale 7. **Request timing** — Machine-speed interactions 8. **Mouse movement** — No mouse events between clicks ### Tier 3: Advanced Detection (Cloudflare, DataDome, PerimeterX) 9. **Canvas fingerprint** — Headless renders differently 10. **WebGL fingerprint** — GPU-specific rendering variations 11. **Audio fingerprint** — AudioContext processing differences 12. **Font enumeration** — Different available fonts in headless 13. **Behavioral analysis** — Scroll patterns, click patterns, reading time ## Stealth Techniques ### 1. WebDriver Flag Removal The most critical fix. Every anti-bot check starts here. ```python await page.add_init_script(""" // Remove webdriver flag Object.defineProperty(navigator, 'webdriver', { get: () => undefined, }); // Remove Playwright-specific properties delete window.__playwright; delete window.__pw_manual; """) ``` ### 2. User Agent Configuration Match the user agent to the browser you are launching. A Chrome UA with Firefox-specific headers is a red flag. ```python # Chrome 120 on Windows 10 (most common configuration globally) CHROME_WIN = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36" # Chrome 120 on macOS CHROME_MAC = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36" # Chrome 120 on Linux CHROME_LINUX = "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36" # Firefox 121 on Windows FIREFOX_WIN = "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:121.0) Gecko/20100101 Firefox/121.0" ``` **Rules:** - Update UAs every 2-3 months as browser versions increment - Match UA platform to `navigator.platform` override - If using Chromium, use Chrome UAs. If Firefox, use Firefox UAs. - Never use obviously fake or ancient UAs ### 3. Viewport and Screen Properties Common real-world screen resolutions (from analytics data): | Resolution | Market Share | Use For | |-----------|-------------|---------| | 1920x1080 | ~23% | Default choice | | 1366x768 | ~14% | Laptop simulation | | 1536x864 | ~9% | Scaled laptop | | 1440x900 | ~7% | MacBook | | 2560x1440 | ~5% | High-end desktop | ```python import random VIEWPORTS = [ {"width": 1920, "height": 1080}, {"width": 1366, "height": 768}, {"width": 1536, "height": 864}, {"width": 1440, "height": 900}, ] viewport = random.choice(VIEWPORTS) context = await browser.new_context( viewport=viewport, screen=viewport, # screen should match viewport ) ``` ### 4. Navigator Properties Hardening ```python STEALTH_INIT = """ // Plugins (headless Chrome has 0 plugins, real Chrome has 3-5) Object.defineProperty(navigator, 'plugins', { get: () => { const plugins = [ { name: 'Chrome PDF Plugin', filename: 'internal-pdf-viewer' }, { name: 'Chrome PDF Viewer', filename: 'mhjfbmdgcfjbbpaeojofohoefgiehjai' }, { name: 'Native Cli