Patchright Deep-Dive: Perché l'Automazione Indetectable Richiede Più di un Fork
Se hai mai provato a automatizzare un browser contro un sito protetto da Cloudflare Turnstile o DataDome, sai che Patchright — il fork undetected di Playwright — risolve solo metà del problema. Chiude le leak CDP più comuni, inietta i flag giusti e ti dà uno stack TLS reale. Ma dopo che il browser è "pulito", il sistema di anti-bot guarda ancora al tuo indirizzo IP. E se quel IP è un datacenter noto, perdi comunque. Questo approfondimento Patchright (Patchright Deep-Dive) copre esattamente quali segnali Patchright patcha, quali lascia aperti, e perché i proxy residenziali restano obbligatori per passare i controlli più aggressivi.
Scriveremo per ingegneri di automazione e ricercatori di sicurezza: niente definizioni generiche, solo segnali concreti, snippet di codice e decisioni architetturali.
Il Contesto Tecnico: Cosa Rilevano gli Anti-Bot Moderni
I sistemi anti-bot non si basano più su un singolo segnale. Combinano fingerprint del browser, leak del protocollo di automazione, reputazione dell'IP e analisi comportamentale. Patchright affronta i primi due; la reputazione IP e il comportamento restano responsabilità tua.
Le piattaforme come Cloudflare Bot Management e DataDome assegnano un punteggio di rischio composito. Un singolo segnale forte — come navigator.webdriver === true o un ClientHello TLS che non corrisponde al User-Agent dichiarato — può far fallire la richiesta immediatamente. Ma anche con tutti i segnali del browser puliti, un IP datacenter con cattiva reputazione abbassa il punteggio sotto la soglia di passaggio.
Segnali di Detection che Patchright Risolve
Patchright, disponibile su GitHub, patcha i segnali di automazione più noti che Playwright lascia esposti. Ecco i principali:
1. navigator.webdriver
Lo standard W3C WebDriver richiede che i browser automatizzati espongano navigator.webdriver = true. Playwright imposta questo flag. Patchright lo rimuove completamente dal prototype chain, non si limita a sovrascriverlo — il che significa che controlli come 'webdriver' in navigator restituiscono false, non solo navigator.webdriver === undefined.
2. CDP Runtime Leaks (Runtime.enable)
Quando Playwright si connette a un browser via Chrome DevTools Protocol, abilita domini come Runtime, Page, Network. Siti sofisticati possono rilevare questi domini attivi tramite timing side-channel o errori di iniezione. Patchright evita di abilitare Runtime.enable dove possibile e patcha le leak più comuni che permettono a una pagina di dedurre la presenza del debugger CDP.
Un esempio concreto: quando Runtime.enable è attivo, la chiamata Error().stack può includere frame di DevTools. Patchright sanifica questi stack trace per rimuovere i riferimenti interni al protocollo di automazione.
3. Command-Flag Tells
Chrome lanciato via Playwright riceve flag come --enable-automation e --disable-extensions che sono rilevabili ispezionando process.argv o, in alcuni casi, attraverso comportamenti del browser stesso (es. la barra "Chrome is being controlled by automated test software"). Patchright:
- Rimuove
--enable-automationdalla command line. - Inietta
--disable-blink-features=AutomationControlled, che disabilita la feature Blink che impostanavigator.webdrivere altri marker di automazione a livello di engine. - Evita flag che creano differenze osservabili rispetto a un Chrome lanciato manualmente.
4. Stack TLS/JA3 Reale con channel='chrome'
Questo è un punto cruciale che molti trascurano. Quando usi Playwright con Chromium bundle (il default), il fingerprint TLS/JA3 del browser non corrisponde a quello di un Chrome reale. Cloudflare e DataDome confrontano il JA3/JA4 con un database di fingerprint noti per browser e versioni.
Patchright raccomanda channel='chrome' per usare l'installazione reale di Chrome sul sistema, non il bundle Chromium. Questo dà un ClientHello TLS identico a quello di un utente reale con la stessa versione di Chrome — stesso cipher suite order, stessi ALPN, stessi extensions. Il JA4 fingerprint corrisponde al User-Agent dichiarato.
Nota tecnica: Il JA4 fingerprint ordina le cipher suites per valore, non per posizione, rendendo il fingerprint stabile attraverso patch di sistema operativo. Un Chromium bundle con TLS di default può avere un JA4 diverso dal Chrome stabile anche a parità di versione.
Cosa Patchright NON Patcha: Canvas, WebGL, Font, Comportamento
Patchright chiude le leak di automazione, ma non crea un fingerprint di browser completamente falso. Ecco cosa rimane scoperto:
Canvas Fingerprinting
Il rendering di canvas dipende dalla GPU, dai driver, dal sistema operativo e dalle impostazioni anti-aliasing. Due macchine diverse producono hash canvas diversi. Patchright non altera il canvas fingerprint — il tuo browser automizzato ha il canvas fingerprint della macchina su cui gira, che potrebbe essere un server Linux senza GPU dedicata, immediatamente anomalo.
WebGL e Parametri GPU
Simile al canvas, WEBGL_debug_renderer_info espone il vendor e il renderer della GPU. Un server headless tipicamente mostra SwiftShader o Google SwiftShader, un segnale fortissimo di ambiente headless. Patchright non patcha questo — devi gestirlo con flag Chrome (--use-gl=angle --use-angle=gl) o con librerie esterne.
Font List
La lista dei font installati è un fingerprint forte. Un container Docker ha tipicamente 3-4 font; un desktop Windows ne ha 200+. Siti che controllano document.fonts o usano misurazioni di testo possono rilevare l'anomalia.
Segnali Comportamentali
Nessun patch del browser risolve il comportamento. Un bot che naviga direttamente alla pagina target senza movimenti del mouse, senza scroll, con timing perfettamente regolari, è rilevabile anche con un browser perfettamente patchato. I sistemi anti-bot più avanzati usano machine learning su pattern di interazione.
Confronto: Patchright vs Camoufox vs playwright-stealth
| Caratteristica | Patchright | Camoufox | playwright-stealth |
|---|---|---|---|
| Base | Fork di Playwright (Node.js/Python) | Firefox custom build (C++/Rust) | Plugin Playwright (JS) |
| navigator.webdriver | d>Rimosso a livello engineRimosso a livello engine | Sovrascritto (non rimosso) | |
| CDP Runtime leaks | Patchate | N/A (usa Firefox, non CDP) | Non patchate |
| Canvas/WebGL spoofing | No | Sì (spoofing nativo) | Parziale |
| Font spoofing | No | Sì | No |
| TLS/JA3 real Chrome | Sì (channel='chrome') | Firefox fingerprint | Parziale |
| Manutenzione attiva | Sì | Sì | Limitata |
Camoufox, disponibile su GitHub, prende un approccio diverso: invece di patchare Playwright, costruisce un Firefox personalizzato con spoofing nativo di canvas, WebGL e font. È più completo per il fingerprinting del browser, ma usa Firefox — il che significa un fingerprint TLS diverso da Chrome, e alcuni siti potrebbero profilare Firefox in modo diverso. playwright-stealth è il più superficiale: sovrascrive proprietà JavaScript ma non tocca il livello CDP o TLS.
Perché la Reputazione IP Conta Ancora Dopo le Patch CDP
Qui arriviamo al cuore del problema. Anche se Patchright chiude ogni leak CDP, rimuove navigator.webdriver, e ti dà un JA3 Chrome reale — il sistema anti-bot guarda ancora al tuo IP.
Cloudflare e DataDome mantengono database di reputazione IP in tempo reale. Gli IP datacenter sono classificati con alto rischio per default. ASN noti (AWS, DigitalOcean, Hetzner, OVH) vengono flaggati automaticamente. Un punteggio di rischio alto sull'IP può far fallire la challenge Turnstile anche con un browser perfetto, o forzare un challenge interattivo (CAPTCHA) che un bot non può risolvere.
I proxy residenziali risolvono questo perché instradano il traffico attraverso IP assegnati a ISP reali — indirizzi che appartengono a utenti domestici, non a cloud provider. La reputazione di questi IP è tipicamente neutra o positiva, perché il traffico quotidiano è quello di un utente reale.
Key Insight: Un browser perfettamente patchato su un IP datacenter fallisce. Un browser con patch minime su un IP residenziale pulito passa. La reputazione IP pesa più dei segnali del browser nei sistemi anti-bot moderni.
Allineamento TLS/HTTP2: Far Coincidere IP e Fingerprint
Un aspetto che ingegneri di automazione esperti sottovalutano: l'IP di uscita e il fingerprint TLS devono essere coerenti. Se il tuo JA3 dice "Chrome 120 su Windows" ma il tuo IP è un mobile carrier in Indonesia con un ASN che non serve Windows desktop, c'è una discrepanza che i sistemi avanzati possono rilevare.
Questo significa:
- Se usi un IP residenziale USA, il tuo browser dovrebbe presentarsi come Chrome su Windows o macOS — i sistemi operativi più comuni per quel pool di IP.
- Se usi un proxy mobile, considera che il fingerprint del browser deve essere coerente con un dispositivo mobile (Chrome su Android, Safari su iOS).
- L'header
Accept-Languagedeve corrispondere alla geolocalizzazione dell'IP. Un IP italiano conAccept-Language: en-USè un segnale debole ma non zero.
Patchright con channel='chrome' su Windows dà un JA4 fingerprint che corrisponde al Chrome stabile. Abbinato a un IP residenziale ProxyHat nello stesso paese del Accept-Language, l'IP e il fingerprint raccontano la stessa storia.
Implementazione Pratica: Patchright con Proxy Residenziali ProxyHat
Vediamo un esempio concreto di automazione legittima — ad esempio, monitoraggio di prezzi pubblici su un sito e-commerce protetto da Cloudflare. Usiamo Patchright in Python con un contesto persistente e un IP residenziale sticky USA.
Installazione
pip install patchright
# Installa Chrome reale (non il bundle Chromium)
patchright install chrome
Script di Automazione
from patchright.sync_api import sync_playwright
def build_proxy_url(country='US', session='abc123'):
"""Costruisce l'URL proxy ProxyHat con geo-targeting e sessione sticky."""
username = f"user-country-{country}-session-{session}"
password = "your_password"
return f"http://{username}:{password}@gate.proxyhat.com:8080"
with sync_playwright() as p:
proxy_url = build_proxy_url(country='US', session='abc123')
browser = p.chromium.launch_persistent_context(
user_data_dir="/tmp/patchright-profile",
channel="chrome", # Usa Chrome reale, non Chromium bundle
headless=False, # headless=True è più rilevabile; usa Xvfb se necessario
proxy={
"server": proxy_url
},
args=[
"--disable-blink-features=AutomationControlled",
"--no-first-run",
"--no-default-browser-check",
],
viewport={"width": 1920, "height": 1080},
locale="en-US",
timezone_id="America/New_York",
)
page = browser.new_page()
# Naviga alla pagina target
page.goto("https://example-ecommerce.com/products", wait_until="domcontentloaded")
# Attendi che il contenuto sia caricato
page.wait_for_selector(".product-price", timeout=15000)
# Estrai i dati
prices = page.query_selector_all(".product-price")
for price_el in prices:
print(price_el.inner_text())
browser.close()
Versione asincrona con gestione sessioni multiple
import asyncio
from patchright.async_api import async_playwright
async def scrape_with_session(country, session_id, url):
proxy_url = f"http://user-country-{country}-session-{session_id}:pass@gate.proxyhat.com:8080"
async with async_playwright() as p:
browser = await p.chromium.launch_persistent_context(
user_data_dir=f"/tmp/profile-{session_id}",
channel="chrome",
headless=False,
proxy={"server": proxy_url},
args=["--disable-blink-features=AutomationControlled"],
locale="en-US",
timezone_id="America/New_York",
)
page = browser.pages[0] if browser.pages else await browser.new_page()
await page.goto(url, wait_until="domcontentloaded")
await page.wait_for_selector(".product-price", timeout=15000)
content = await page.content()
await browser.close()
return content
# Esegui 5 sessioni concorrenti con IP diversi
async def main():
tasks = [
scrape_with_session("US", f"sess-{i}", "https://example-ecommerce.com/products")
for i in range(5)
]
results = await asyncio.gather(*tasks)
print(f"Raccolte {len(results)} pagine")
asyncio.run(main())
Configurazione SOCKS5 (quando serve)
# Per scenari che richiedono SOCKS5
proxy_url = "socks5://user-country-US-session-abc123:pass@gate.proxyhat.com:1080"
Verifica del fingerprint
Prima di automatizzare produzione, verifica che il tuo setup passi i test di fingerprinting:
- Naviga su bot.sannysoft.com e controlla che tutti i test siano verdi.
- Verifica il JA4 fingerprint con strumenti come
ja3er.como implementazioni locali e confrontalo con un Chrome reale. - Controlla
navigator.webdriver,window.chrome, e le proprietà CDP con script manuali.
Errori Comuni e Edge Case
Headless mode
Patchright in modalità headless=True è ancora rilevabile da molti segnali. Le differenze nel rendering, nei font, e nel comportamento del GPU creano discrepanze. Usa headless=False con Xvfb su Linux, o headless='new' (la nuova modalità headless di Chrome che è meno distinguibile) se devi.
User-Agent mismatch
Non cambiare il User-Agent manualmente. Patchright con channel='chrome' imposta un UA coerente con il Chrome reale installato. Se modifichi l'UA, il fingerprint TLS non corrisponderà più.
Sessioni troppo lunghe
Una sessione sticky su un IP residenziale per ore è sospetta — gli utenti reali non restano sulla stessa pagina per 6 ore. Ruota le sessioni ogni 10-30 minuti per attività continue, o usa rotazione per-request per richieste indipendenti.
Concorrenza eccessiva
Anche con IP diversi, 100 richieste concorrenti dalla stessa macchina con lo stesso fingerprint browser crea un pattern rilevabile. Limita la concorrenza a 5-10 sessioni per macchina e distribuisci nel tempo.
Dimenticare i header HTTP
Il browser gestisce la maggior parte degli header, ma se inietti header custom (es. page.set_extra_http_headers()), assicurati che siano coerenti. Un header sec-ch-ua che non corrisponde alla versione di Chrome reale è un segnale forte.
Quando Usare Patchright con Proxy: Casi d'Uso Appropriati
Questa combinazione è appropriata per:
- Ricerca di sicurezza autorizzata: pentest con scope approvato, bug bounty program, analisi di vulnerabilità su infrastrutture proprie o autorizzate.
- Automazione di dati pubblici conformi: raccolta di dati pubblicamente accessibili nel rispetto di
robots.txte dei termini di servizio, per ricerca di mercato, monitoraggio prezzi, analisi SERP. - QA e testing: test end-to-end su piattaforme proprie con protezione anti-bot attiva.
Non è appropriato per:
- Creazione di account falsi o bypass di login-wall.
- Acquisto massivo di biglietti o sneaker in violazione dei ToS.
- Fraud, spam, o qualsiasi attività che viola leggi locali o termini di servizio.
Rispetta sempre robots.txt, i termini di servizio, e le normative sulla protezione dei dati (GDPR, CCPA). L'uso di tecniche di evasione anti-bot non ti esime dal rispetto legale.
ProxyHat: Configurazione e Best Practice
ProxyHat offre proxy residenziali, mobile e datacenter. Per l'uso con Patchright contro siti protetti, i residenziali sono la scelta corretta. Ecco alcune considerazioni di configurazione:
- Geo-targeting: usa
country-USper IP USA, o scendi a livello città concountry-US-city-newyorkper coerenza geografica. - Sessioni sticky: usa
session-abc123per mantenere lo stesso IP durante una sessione di navigazione. Cambia l'ID sessione per ottenere un nuovo IP. - Rotazione per-request: ometti il flag session per ruotare l'IP ad ogni richiesta — utile per scraping massivo di pagine indipendenti.
- Porte: HTTP su
8080, SOCKS5 su1080. Usa HTTP per la maggior parte dei casi; SOCKS5 per traffico non-HTTP o quando il target richiede SOCKS5.
Consulta la documentazione ProxyHat per dettagli completi su autenticazione, geo-targeting e limiti di concorrenza. Per i prezzi e i pani disponibili, visita la pagina pricing. Per le posizioni disponibili, consulta locations.
Key Takeaways
- Patchright chiude le leak CDP e di automazione (navigator.webdriver, Runtime.enable, flag command-line) ma non patcha canvas, WebGL, font o comportamento.
- Il TLS/JA3 fingerprint conta: usa
channel='chrome'per un ClientHello identico al Chrome reale, coerente con il User-Agent. - La reputazione IP pesa più delle patch del browser: un browser perfetto su IP datacenter fallisce; un browser minimo su IP residenziale passa.
- IP e fingerprint devono essere coerenti: geo-targeting, Accept-Language, timezone e sistema operativo devono raccontare la stessa storia.
- Usa proxy residenziali con sessioni sticky per navigazione continua, rotazione per-request per scraping massivo.
- Limita la concorrenza a 5-10 sessioni per macchina e ruota le sessioni ogni 10-30 minuti.
- Rispetta robots.txt, ToS e normative — l'automazione legittima è ricerca di sicurezza autorizzata o raccolta di dati pubblici conformi.
Per approfondire casi d'uso specifici di web scraping e SERP tracking con ProxyHat, visita le pagine web scraping e SERP tracking.






