Reading layout

How to Configure Selenium Stealth to Avoid Detection

Selenium Stealth is a lightweight Python library designed to patch the default WebDriver configuration, masking automation fingerprints that trigger modern anti-bot systems. Unlike standard drivers, it modifies navigator.webdriver, WebGL parameters, and Chrome runtime properties to mimic human browsing behavior. Implementing these adjustments is a foundational step in Advanced Scraping Techniques & Anti-Bot Evasion, ensuring your automation scripts bypass basic heuristic checks without sacrificing execution speed or stability.

Installation & Environment Setup

Before configuring stealth parameters, ensure your environment has compatible dependencies. selenium-stealth operates alongside standard Selenium and requires a matching ChromeDriver version. Use webdriver_manager to automate binary downloads and prevent version mismatch errors. Avoid installing conflicting extensions or legacy undetected drivers that may override stealth patches during initialization.

pip install selenium selenium-stealth webdriver-manager

Core Stealth Configuration Parameters

The stealth() function accepts multiple boolean flags and string overrides that directly alter browser fingerprinting. Key parameters include lang, vendor, platform, webgl_vendor, renderer, fix_hairline, and run_on_insecure_origins. Properly aligning these values with a realistic browser profile prevents mismatched fingerprinting. Always inject stealth immediately after driver initialization but before navigating to any target URL to ensure patches apply to the first request.

Advanced Fingerprint Masking & Proxy Integration

To scale operations reliably, combine stealth settings with authenticated proxy endpoints. Route traffic through residential or datacenter proxies while maintaining consistent User-Agent strings and locale headers. For complex SPAs that require persistent sessions and dynamic DOM rendering, pair your stealth setup with Mastering Selenium for Dynamic Websites to synchronize header injection with JavaScript execution flows.

Validation & Troubleshooting Detection Flags

Verify your configuration by visiting fingerprinting validation endpoints like bot.sannysoft.com or amiunique.org. Check for navigator.webdriver === false, a populated plugins array, and valid chrome.runtime objects. If blocked, temporarily disable headless mode to debug TLS handshake mismatches, verify proxy geolocation alignment with browser locale, and ensure ChromeDriver matches your installed Chrome version exactly.

Code Examples

Basic Selenium Stealth Initialization

from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium_stealth import stealth
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.chrome.service import Service

chrome_options = Options()
chrome_options.add_argument("--disable-blink-features=AutomationControlled")
chrome_options.add_argument("--no-sandbox")
chrome_options.add_argument("--disable-dev-shm-usage")

driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()), options=chrome_options)

stealth(driver,
 languages=["en-US", "en"],
 vendor="Google Inc.",
 platform="Win32",
 webgl_vendor="Intel Inc.",
 renderer="Intel Iris OpenGL Engine",
 fix_hairline=True,
 run_on_insecure_origins=False)

driver.get("https://bot.sannysoft.com")
print(driver.title)
driver.quit()

Explanation: This snippet initializes a standard ChromeDriver, applies core stealth patches via the stealth() function, and validates the configuration against a public fingerprint checker. The --disable-blink-features=AutomationControlled flag provides an additional layer of detection masking.

Stealth with Proxy & Custom Headers

from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium_stealth import stealth

PROXY = "http://user:pass@proxy-ip:port"

chrome_options = Options()
chrome_options.add_argument(f"--proxy-server={PROXY}")
chrome_options.add_argument("--disable-blink-features=AutomationControlled")
chrome_options.add_experimental_option("excludeSwitches", ["enable-automation"])

driver = webdriver.Chrome(options=chrome_options)

stealth(driver,
 languages=["en-US", "en"],
 vendor="Google Inc.",
 platform="Win32",
 webgl_vendor="Intel Inc.",
 renderer="Intel Iris OpenGL Engine",
 fix_hairline=True)

driver.get("https://httpbin.org/ip")
print(driver.page_source)
driver.quit()

Explanation: Demonstrates routing stealth-configured traffic through an authenticated proxy while excluding the enable-automation switch. This prevents Chrome from injecting the navigator.webdriver flag at the browser level before Python patches are applied.

Common Mistakes

  • Applying stealth patches after calling driver.get(), which leaves the initial request exposed to bot detection.
  • Hardcoding outdated User-Agent strings that conflict with the actual Chrome version being automated.
  • Running headless mode without the --disable-blink-features=AutomationControlled flag, which leaks automation markers.
  • Mismatching proxy IP geolocation with browser locale and timezone settings, triggering behavioral anomaly flags.
  • Overriding navigator.webdriver manually via execute_script instead of using the library's native patching, causing inconsistent DOM state.

Frequently Asked Questions

Is selenium-stealth better than undetected-chromedriver? Selenium-stealth is a lightweight patching library that modifies WebDriver properties on a standard ChromeDriver, offering faster execution and easier maintenance. Undetected-chromedriver patches the browser binary itself, which can be more robust against advanced TLS fingerprinting but often suffers from slower startup times and compatibility issues with newer Chrome versions.

Does selenium-stealth work in headless mode? Yes, but it requires additional Chrome arguments like --disable-blink-features=AutomationControlled and --headless=new. Headless mode inherently leaks rendering differences, so combining stealth patches with proper viewport sizing and WebGL spoofing is necessary to maintain consistency.

How often should I update ChromeDriver for stealth configurations? Update ChromeDriver immediately whenever your local or server Chrome browser updates. Version mismatches cause WebDriver session failures and can break stealth patches that rely on specific browser APIs. Use webdriver-manager to automate this synchronization.

Can selenium-stealth bypass Cloudflare Turnstile or reCAPTCHA v3? Selenium-stealth masks browser fingerprints and reduces heuristic detection, but it does not solve cryptographic challenges like Turnstile or reCAPTCHA v3. For those, you must integrate third-party solving APIs, residential proxies with high trust scores, or behavioral automation patterns that mimic human interaction timing.