
invisible_playwright v0.7.0
Antidetect browser gratuito e stealth per Playwright: impronta digitale di Firefox headless non rilevata. Scraping Python, bypass di recaptcha e rilevamento bot. Open source
Stealth antidetect browser gratuito per Playwright: fingerprint Firefox non rilevabile, headless o headed.
Web scraping in Python e bypass dei captcha. Open source, e supera ogni test di rilevamento bot.

Come funziona
Gli anti-bot pongono due domande, e reCAPTCHA, hCaptcha e Cloudflare Turnstile valutano le risposte. invisible_playwright risponde sì a entrambe.
1. È un browser reale? Sì. È Firefox, modificato a livello del codice sorgente C++.
- Il fingerprint del browser è impostato all'interno del motore, non iniettato nella pagina: navigator, screen, GPU/WebGL, canvas, font, audio, WebRTC, fuso orario, rete. Headless o headed, gli stessi valori in entrambi i casi.
- Nessuno shim JS, nessun override, nessuna giuntura da leggere.
2. Lo sta usando una persona reale? Sì. Le azioni sono umanizzate nel driver.
- Ogni clic, hover e trascinamento segue un percorso naturale del mouse con tempi umani, nessun cursore che si teletrasporta.
- Ogni input è identico byte per byte a quello di un mouse reale: sorgente di input reale, pressione, eventi trusted.
Installazione
pip install invisible-playwright
python -m invisible_playwright fetch # one-time download, sha256-verified: 240 MB (Windows) / 262 MB (Linux x86_64) / 253 MB (Linux arm64), about 550 MB unpacked
Richiede Python 3.11 o superiore.
Piattaforme supportate: Windows x86_64, Linux x86_64 / arm64.
Utilizzo
Fingerprint casuale per sessione
L'API di Playwright, sync e async, senza modifiche al codice. Gli stessi oggetti, le stesse chiamate, gli stessi valori di ritorno. Alcune superfici sono fuori ambito - tracing, HAR, CDP, il contesto di richiesta API - e go_back() e go_forward() sono trattenuti da un difetto nelle pagine ripristinate; ognuno rifiuta con una frase che spiega il motivo invece di comportarsi male in silenzio. Se già usi Playwright, passare richiede due righe:
- 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:
Ogni sessione ottiene un fingerprint distinto (GPU, audio, font, schermo, ~200 campi) e un movimento del mouse a curva di Bezier.
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")
L'oggetto browser è un playwright.sync_api.Browser / playwright.async_api.Browser - ogni metodo di Playwright funziona così com'è.
Registra il seed per riprodurre un'esecuzione:
sf = InvisiblePlaywright()
with sf as browser:
print("seed =", sf.seed)
# ...
Fingerprint riproducibile
with InvisiblePlaywright(seed=42) as browser:
... # same GPU, same canvas hash, same audio context, every run
Proxy
proxy = {
"server": "socks5://gate.example.com:1080",
"username": "user",
"password": "pass",
}
with InvisiblePlaywright(proxy=proxy) as browser:
...
Schemi supportati: socks5, socks4, http, https. Il DNS è instradato attraverso il proxy per impostazione predefinita, nessuna fuga locale.
Fuso orario
Il fuso orario del browser segue 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:
...
Fissare campi specifici del fingerprint
Per impostazione predefinita tutto deriva da seed. Per forzare valori specifici mentre il resto rimane derivato dal seed:
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:
...
Un pin sulla GPU seleziona una delle persona validate anziché impostare una stringa libera,
perché i ~81 valori di getParameter e la lista delle estensioni viaggiano con il
nome del renderer e un rilevatore li verifica incrociandoli con esso. Un nome che il pool
non contiene genera un errore, e l'errore elenca quelli che invece contiene.
L'elenco completo delle chiavi fissabili, come il pinning interagisce con il campionatore bayesiano e i pattern comuni sono in docs/pinning.md.
CLI
Il comando installato è invisible-playwright, con il trattino. python -m invisible_playwright funziona in modo identico e non richiede nulla nel 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
Documentazione, guide e confronti
Se preferisci usare un prompt invece di uno script. Questa pagina è il motore, come
libreria Python. Due modi per usarlo senza scrivere codice, entrambi in una riga: da un client MCP
che già possiedi (Claude Code, Claude Desktop, Cursor),
claude mcp add stealth -- uvx aihawk, vedi
la pagina del server MCP; oppure con
un'interfaccia e un modello inclusi, che richiede solo una chiave OpenRouter,
uvx aihawk ui --openrouter-key sk-or-..., vedi
AIHawk. Lo stesso motore sotto, e il secondo
è un client del primo.
Tutto si legge meglio, ed è ricercabile, nella wiki, organizzata in quattro sezioni invece di un unico elenco piatto: