Scraping Central is reader-supported. When you buy through links on our site, we may earn an affiliate commission.

Browser Fingerprinting and Stealth Mode

Learn how websites detect automated browsers through fingerprinting and how to use stealth plugins to avoid detection while scraping.

Browser Automation · #9advanced2 min read
Share:WhatsAppLinkedIn

Websites use browser fingerprinting to distinguish automated scrapers from real users. They check dozens of signals including the navigator object, WebGL rendering, canvas fingerprints, installed plugins, and more. A default Selenium or Playwright instance leaks many signals that reveal it as automated.

How Websites Detect Automation

Common detection signals include:

  • navigator.webdriver is true in automated browsers
  • Missing or inconsistent browser plugins
  • WebGL vendor and renderer strings
  • Canvas fingerprint anomalies
  • Consistent viewport sizes and screen resolutions
  • Missing or robotic mouse movements
  • CDP (Chrome DevTools Protocol) detection

Playwright Stealth with playwright-stealth

The playwright-stealth package patches common detection leaks:

pip install playwright-stealth
from playwright.sync_api import sync_playwright
from playwright_stealth import stealth_sync

with sync_playwright() as p:
    browser = p.chromium.launch(headless=True)
    page = browser.new_page()

    # Apply stealth patches
    stealth_sync(page)

    page.goto("https://bot.sannysoft.com")
    page.wait_for_load_state("networkidle")

    # Take a screenshot to verify stealth is working
    page.screenshot(path="stealth_test.png", full_page=True)

    browser.close()

Selenium with undetected-chromedriver

For Selenium, undetected-chromedriver patches ChromeDriver to avoid detection:

pip install undetected-chromedriver
import undetected_chromedriver as uc

driver = uc.Chrome(headless=True)
driver.get("https://bot.sannysoft.com")

# Check if detection tests pass
print(driver.title)
driver.save_screenshot("selenium_stealth.png")

driver.quit()

Manual Stealth Techniques

You can also apply patches manually for more control:

from playwright.sync_api import sync_playwright

with sync_playwright() as p:
    browser = p.chromium.launch(
        headless=True,
        args=[
            "--disable-blink-features=AutomationControlled",
        ]
    )
    context = browser.new_context(
        user_agent="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",
        viewport={"width": 1366, "height": 768},
        locale="en-US",
        timezone_id="America/New_York",
    )
    page = context.new_page()

    # Override navigator.webdriver
    page.add_init_script("""
        Object.defineProperty(navigator, 'webdriver', {
            get: () => undefined
        });
    """)

    page.goto("https://example.com")
    browser.close()

Human-Like Behavior

Add realistic delays and mouse movements to avoid behavioral detection:

import random
import time

# Random delay between actions
time.sleep(random.uniform(1, 3))

# Type like a human (with random delays between keystrokes)
for char in "search query":
    page.type("#search", char, delay=random.randint(50, 150))

The Easier Path

Maintaining stealth configurations is a constant cat-and-mouse game. Anti-bot services update their detection methods regularly. ScrapingAnt and ScraperAPI maintain stealth browser profiles on their end, so you get clean data without managing fingerprint evasion yourself.

Next Steps

  • Set up proxies with Playwright and Selenium
  • Learn anti-detection techniques in depth
  • Compare browser automation tools