Anti-bots ask two questions, and reCAPTCHA, hCaptcha and Cloudflare Turnstile score the answers. invisible_selenium answers yes to both.
1. Is this a real browser? Yes. It is Firefox, patched at the C++ source level.
- The browser fingerprint is set inside the engine, not injected into the page: navigator, screen, GPU/WebGL, canvas, fonts, audio, WebRTC, timezone, network. Headless or headed, the same values either way.
- No geckodriver and no Marionette, so nothing turns
navigator.webdriveron, and no JavaScript shim for a page to find.
2. Is a real person using it? Yes. The actions are humanized in the driver.
- Every click, hover and drag follows a natural mouse path with human timing, no teleporting cursor.
- Input goes through the browser's real input path, so the page sees trusted events.
Windows, in PowerShell:
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
$env:Path = "$env:USERPROFILE\.local\bin;$env:Path"
uv init --python ">=3.11" my-project
cd my-project
uv add invisible-selenium
uv run invisible-selenium fetchLinux:
curl -LsSf https://astral.sh/uv/install.sh | sh
source $HOME/.local/bin/env
uv init --python ">=3.11" my-project
cd my-project
uv add invisible-selenium
uv run invisible-selenium fetchSupported platforms: Windows x86_64 / ARM64 (the x86_64 engine, under Windows' own emulation), Linux x86_64 / arm64.
Then save one of the examples below as main.py in my-project and run it with uv run main.py.
Selenium's API, with no code changes. The same webdriver, By, WebDriverWait and expected_conditions. If you already use Selenium, switching is the import:
- from selenium import webdriver
- from selenium.webdriver.common.by import By
+ from invisible_selenium import webdriver
+ from invisible_selenium.webdriver.common.by import Byfrom invisible_selenium import webdriver
from invisible_selenium.webdriver.common.by import By
from invisible_selenium.webdriver.support.ui import WebDriverWait
from invisible_selenium.webdriver.support import expected_conditions as EC
driver = webdriver.Firefox()
driver.get("https://example.com")
WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.TAG_NAME, "a"))).click() # the mouse arcs to the link
print("seed =", driver.seed) # log it to replay the run
driver.quit()Every session gets a distinct fingerprint (GPU, audio, fonts, screen, ~200 fields). Do not install Selenium alongside it: this package already implements its API.
driver = webdriver.Firefox(
seed=42, # same seed, same fingerprint, every run
proxy={"server": "socks5://host:1080", "username": "u", "password": "p"},
timezone="America/New_York", # default: derived from the proxy's exit IP
pin={"screen.width": 2560, "screen.height": 1440}, # force fields, the rest stays seed-derived
headless=True, # hidden desktop, real rendering: same fingerprint as headed
profile_dir="./profile", # cookies and storage survive the run
)Proxies can be socks5, socks4, http or https, and DNS goes through them too. FirefoxOptions work as they do in Selenium, -headless included. The fields you can pin are the same as in invisible_playwright: pinning.
invisible-selenium fetch # download the engine if missing, check every cached one, print the path
invisible-selenium version # wrapper, core and engine versions- invisible_playwright: the same engine with Playwright's API, and the guides on how detection works.
- invisible_puppeteer: the same engine with Puppeteer's API, in Python.
- invisible_playwright_mcp: the same engine for AI agents, over MCP.
- invisible_core: turns a seed into a fingerprint and the fingerprint into Firefox preferences. This package depends on an exact version of it.
- firefox_antidetect_patch: the C++ patches that build the browser.
Switching from another tool?
- selenium-stealth: it patches the page from JavaScript, and its last commit is from December 2021. What that means.
The setup and the test commands are in CONTRIBUTING.md.
MIT, see LICENSE. The Juggler client it drives the browser with lives in invisible-core, which carries two files taken from Playwright's driver under Apache-2.0. The patched Firefox binary is MPL-2.0, built from feder-cr/firefox_antidetect_patch.
This project is for educational purposes only. It is provided as-is, with no warranties. I take no responsibility for how it is used. Use it at your own risk and in compliance with the laws of your jurisdiction.
Built by Federico Elia