invisible_playwright

feder-crMIT活跃维护

基于 Playwright 的隐身无头 Firefox,保持原有 API 不变,通过伪造指纹绕过 Cloudflare、Akamai 等反爬检测,避免触发验证码,适合网页抓取和浏览器自动化。

Playwright that anti-bots cannot see, so no captchas: same API, anti-detect stealth headless Firefox, undetected fingerprint, bypass bot detection, Python web scraping and browser automation.

v0.47.1发布于 2026-11-08 17:12 UTC2,565star +6 / 7 天275fork同步于 2026-11-10 17:45 UTC

怎么上手

由 README 提炼,执行前请确认
uv init --python ">=3.11" my-project
cd my-project
uv add invisible-playwright
uv run invisible-playwright fetch
硬件要求按 README 说明

README 未说明显存或 GPU 要求;支持平台为 Windows x86_64 和 Linux x86_64,Linux arm64 自 firefox-56 起不再支持。

下载:源码 zip·GitHub Releases(安装包)本站不镜像安装包

项目说明

由 README 自动翻译提炼

基于反检测 Firefox 的 Playwright 替代品,让爬虫和自动化脚本不被反爬系统识别

基于 Playwright 的隐身无头 Firefox,保持原有 API 不变,通过伪造指纹绕过 Cloudflare、Akamai 等反爬检测,避免触发验证码,适合网页抓取和浏览器自动化。

核心能力

  • 在 C++ 源码层修改 Firefox,指纹在引擎内设置而非注入页面
  • 每次会话生成独立指纹,覆盖 GPU、音频、字体、屏幕等约 200 个字段
  • 鼠标点击、悬停、拖拽沿贝塞尔曲线移动,模拟真人操作时序
  • API 与 Playwright 完全兼容,同步异步均可,切换只需改两行导入
  • 支持 seed 复现指纹,可 pin 指定 GPU、屏幕等字段,代理 DNS 走代理不泄漏

容易踩的坑

首次使用需运行 invisible-playwright fetch 下载约 240~262 MB 的引擎(解压后约 550 MB);tracing、HAR、CDP、API request context 等接口不支持,调用会直接报错;Linux arm64 平台已不再支持。

内容由模型根据 README 生成,可能不完整或不准确,以官方文档为准。看原文 README

最近发版

5 个版本v0.47.1
  1. v0.47.1最新正式版2026-11-08 · 2026-11-08 17:12 UTC

    Changed

    • invisible-core 58.56.0, which this version pins. A persona has the keyboards Windows installs with its language and country, read from Windows' locale.nls (English US besides Persian, Azerbaijani, Bashkir, Cherokee and Sakha; Russian besides Belarusian, Tatar and Armenian; Hindi Traditional for Hindi), and switches as a user does: left Alt + Shift to the next language, Ctrl + Shift to the next keyboard of the same language. The keyboard pref carries Windows' own form (LANGID:KLID joined by semicolons).
  2. v0.47.02026-11-08 · 2026-11-08 14:50 UTC
    查看更新说明

    Changed

    • Engine firefox-58 (Firefox 159.0), through invisible-core 58.55.0, which this version pins.
    • A persona has the keyboards Windows installs with its language: the language's, and the second one (English US with Russian, Greek, Arabic, Hebrew and most languages not written in Latin letters). A character the active keyboard lacks is typed on the other one, after left Alt + left Shift, Windows' default switch; press("x") on a Russian or Greek session no longer raises "unknown key". Only a character no keyboard has is inserted as text.
    • scroll_into_view_if_needed() is the engine's own scroll, only when needed.

    Fixed

    • In the engine: a navigation Firefox refuses before any channel (a restricted port) ends with its error instead of never; a request held by route() that the page cancels is no longer held; unroute with a request that can no longer be resumed no longer fails; a session cookie set with expires: -1 is kept, sameSite: "None" is SameSite=None, and a cookie Firefox refuses fails add_cookies() with Firefox's reason.
  3. v0.46.42026-11-08 · 2026-11-08 11:55 UTC
    查看更新说明

    Fixed

    • The engine and the GeoIP database install when GitHub's direct release links fail. Through invisible-core 57.54.0, which this version pins: each release file is fetched from the API route first and from the direct link second, and one download attempt tries both, so a 504 on one route is served by the other at once. On 2026-11-08 every direct link answered 504 while the API route served the same files.
  4. v0.46.32026-11-08 · 2026-11-08 08:34 UTC
    查看更新说明

    Changed

    • Engine firefox-57 (Firefox 159.0), through invisible-core 57.53.0, which this version pins. The WebGL extensions a page sees are decided once, by the engine's WebGL host, from the persona's declared list: the content process no longer has a list of its own, an extension the host's GPU cannot serve is never created (its calls stay harmless), and getSupportedExtensions() lists them in Firefox's own order, the only order a retail Firefox gives (the WebGL 1 list had EXT_sRGB before EXT_shader_texture_lod).
  5. v0.46.22026-11-07 · 2026-11-07 19:16 UTC
    查看更新说明

    Changed

    • The persona types on the keyboard a Windows install gives its language in its country, for every language: German in Switzerland on the Swiss keyboard, Dutch on US-International, Polish, Czech, Turkish, Greek, Hebrew, Arabic and the rest on their own keyboards; a language Windows has no profile for takes the keyboard of the country's main language; Japanese and Korean type on the keyboard under the IME. The session passes its country to the server, which only had the language list before. The tables come from invisible-core 56.53.0, which this version pins, read from the bytes of the Windows layout files rather than from the machine.

用户点评

登录用户的真实使用记录,可按版本和硬件筛选
共 0 条

    还没有人点评。第一个说出真实体验的人最有价值。

    README 原文

    未翻译

    invisible_playwright - 5/5 detection suites passed

    How it works

    Anti-bots ask two questions, and reCAPTCHA, hCaptcha and Cloudflare Turnstile score the answers. invisible_playwright 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 JS shim, no override, no seam to read.

    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.
    • Each input is byte-identical to a real mouse: real input source, pressure, trusted events.

    Install

    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-playwright
    uv run invisible-playwright fetch      # one-time download, sha256-verified: 240 MB, about 550 MB unpacked
    

    Linux:

    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-playwright
    uv run invisible-playwright fetch      # one-time download, sha256-verified: 262 MB, about 550 MB unpacked
    

    Supported platforms: Windows x86_64, Linux x86_64. Linux arm64 is no longer supported from firefox-56 (firefox-55 is the last engine built for it).

    Then save one of the examples below as main.py in my-project and run it with uv run main.py.


    Usage

    Random fingerprint per session

    Playwright's API, sync and async, with no code changes. The same objects, the same calls, the same return values. A few surfaces are out of scope - tracing, HAR, CDP, the API request context - and each one refuses with a sentence saying why rather than misbehaving quietly. If you already use Playwright, switching is two lines:

    - from playwright.sync_api import sync_playwright
    - with sync_playwright() as p:
    -     browser = p.firefox.launch()
    + from invisible_playwright import InvisiblePlaywright
    + with InvisiblePlaywright() as browser:
    

    Every session gets a distinct fingerprint (GPU, audio, fonts, screen, ~200 fields) and Bezier-curve mouse motion.

    Sync

    from invisible_playwright import InvisiblePlaywright
    
    with InvisiblePlaywright(proxy={"server": "socks5://...", "username": "u", "password": "p"}) as browser:
        page = browser.new_page()
        page.goto("https://example.com")
        page.click("#submit")   # mouse arcs to the button on a Bezier curve
    

    Async

    from invisible_playwright.async_api import InvisiblePlaywright
    
    async with InvisiblePlaywright(proxy={"server": "socks5://...", "username": "u", "password": "p"}) as browser:
        page = await browser.new_page()
        await page.goto("https://example.com")
        await page.click("#submit")
    

    The browser object is a playwright.sync_api.Browser / playwright.async_api.Browser - every Playwright method works as-is.

    Log the seed to replay a run:

    sf = InvisiblePlaywright()
    with sf as browser:
        print("seed =", sf.seed)
        # ...
    

    Reproducible fingerprint

    with InvisiblePlaywright(seed=42) as browser:
        ...   # same GPU, same canvas hash, same audio context, every run
    

    Proxies

    proxy = {
        "server": "socks5://gate.example.com:1080",
        "username": "user",
        "password": "pass",
    }
    with InvisiblePlaywright(proxy=proxy) as browser:
        ...
    

    Schemes supported: socks5, socks4, http, https. DNS is routed through the proxy by default, no local leak.

    Timezone

    The browser timezone follows timezone=:

    # default: timezone is auto-derived from the egress IP (proxy egress if a
    # proxy is set, otherwise the host's own public IP)
    with InvisiblePlaywright(proxy=proxy) as browser:
        ...
    
    # explicit IANA zone always wins, the only way to force a specific zone
    with InvisiblePlaywright(proxy=proxy, timezone="America/New_York") as browser:
        ...
    

    Pinning specific fingerprint fields

    By default everything comes from seed. To force specific values while the rest stays seed-derived:

    with InvisiblePlaywright(
        seed=42,
        pin={
            "gpu.renderer": "ANGLE (AMD, Radeon R9 200 Series Direct3D11 vs_5_0 ps_5_0, D3D11)",
            "gpu.vendor":   "Google Inc. (AMD)",
            "screen.width":  2560,
            "screen.height": 1440,
            "hardware.concurrency": 16,
        },
    ) as browser:
        ...
    

    A GPU pin picks one of the validated personas rather than setting a free string, because the ~81 getParameter values and the extension list travel with the renderer name and a detector cross-checks them against it. A name the pool does not carry raises, and the error lists the ones it does.

    Full list of pinnable keys, how pinning interacts with the Bayesian sampler, and common patterns are in docs/pinning.md.


    CLI

    The installed command is invisible-playwright, with a hyphen. python -m invisible_playwright works identically and needs nothing on PATH.

    invisible-playwright fetch    # download the engine if missing, check every cached
                                  # one against the seal, print the path
    invisible-playwright version  # wrapper, core and engine versions, and where the
                                  # engine is cached
    

    Documentation, guides and comparisons

    If you would rather prompt than script. This page is the engine, as a Python library. Two ways to use it without writing code, both one line: from an MCP client you already have (Claude Code, Claude Desktop, Cursor), claude mcp add stealth -- uvx aihawk, see the MCP server page; or with an interface and a model included, needing only an OpenRouter key, uvx aihawk ui --openrouter-key sk-or-..., see AIHawk. Same engine underneath, and the second is a client of the first.

    All of it reads better, and is searchable, in the wiki, organised into four sections instead of one flat list:

    • Documentation - installation, the two-line switch from plain Playwright, proxy/timezone configuration, pinning specific fields, the CLI.
    • Guides - how detection actually works, in seven groups: browser identity, canvas/WebGL/fonts/ audio, network and WebRTC, the automation layer, AI agents, the detectors themselves explained from source, and testing.
    • Comparisons - against Camoufox, Patchright, nodriver and playwright-stealth, and the case for Firefox over Chromium generally.
    • Integrations - Scrapy, Crawlee, Robot Framework, CodeceptJS, test runners, Playwright MCP, and the frameworks it does not fit, by name.

    If you don't know where to start: Three ways to make Playwright undetected is the map most other pages link back to, Playwright detected as a bot on one site is the troubleshooting order, and navigator.webdriver is not the tell you think it is explains the most famous property in this space and why patching it alone buys you almost nothing.

    The detectors section now covers the commercial anti-bot products by name, each read from its own documentation or from confirmed reverse engineering: Cloudflare Bot Management and Turnstile, DataDome, Kasada, Akamai Bot Manager, PerimeterX, hCaptcha, Imperva, and the rest of the set.

    Related projects

    The other pieces of this one. The engine is the middle of three, and the two around it are how most people reach it:

    • invisible_core - seed to fingerprint to preferences, plus proxy and geolocation. This package pins it.
    • AIHawk - this engine as an MCP server (uvx aihawk, for any client that brings its own model) and, in the same package, an interface with a model included, from one command. The interface is a client of the server, with no private path to the browser.

    The open-source neighbours. Which one fits depends on the layer your problem is at, and on whether you need Firefox or Chromium: three ways to make Playwright undetected works through what each layer can reach, and AI browser agents and stealth covers the frameworks that pick Chromium over CDP for you.

    On the Firefox side

    • Camoufox - patches C++ too, wider surface, ships a fingerprint database instead of deriving one from a seed. Comparison.
    • LibreWolf - a privacy-defaults Firefox to browse with, not to automate.
    • arkenfox/user.js - hardening through preferences. Where a preference is enough, use it.

    On the Chromium side


    What is patched in the engine

    Two rules hold across everything below. Every value is decided before a page can ask, inside the browser, so there is no JavaScript shim to find. And every value comes from one profile, so no two surfaces contradict each other, which is how a spoofed browser is usually caught. Source: feder-cr/firefox_antidetect_patch.

    Identity

    Rendering

    Audio and media

    Network

    The automation layer


    License

    MIT - see LICENSE. The patched Firefox binary is distributed under the MPL-2.0 (Firefox upstream license). The C++ patches against mozilla-central that produce that binary are at feder-cr/firefox_antidetect_patch.


    Disclaimer

    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.