← Torna al blog

Perché il parser viene rilevato tramite l'impronta TLS anche con un IP residenziale pulito: come verificare e risolvere

Un IP residenziale non protegge dalla blocco se l'impronta TLS del parser è diversa da quella di un normale browser. Analizziamo come verificarlo e configurarlo correttamente.

📅28 settembre 2026

Hai acquistato un costoso IP residenziale, hai impostato la rotazione, hai inserito un User-Agent realistico — eppure il parser finisce comunque in captcha o riceve una risposta vuota. Il problema è quasi sempre nell'IP, ma nel TLS-fingerprint: la libreria con cui invii la richiesta HTTPS "suona" diversamente da un vero browser. I sistemi anti-bot di Wildberries, Ozon, Cloudflare e Akamai lo vedono prima ancora di controllare il tuo indirizzo IP.

Che cos'è il TLS-fingerprint e perché è più importante dell'IP

Quando un client stabilisce una connessione HTTPS, invia al server un pacchetto ClientHello — parte del TLS-handshake. In esso sono criptati l'elenco delle versioni TLS supportate, il set di cifrature (cipher suites), l'ordine delle estensioni (extensions), le curve ellittiche e gli algoritmi di compressione. Questo insieme di parametri è unico per ogni combinazione "libreria + sistema operativo + versione del TLS-stack".

Chrome, Firefox e Safari formano il ClientHello in modo diverso, e questo insieme praticamente non cambia da richiesta a richiesta — a differenza dell'IP o dell'User-Agent, che possono essere facilmente falsificati. Le librerie HTTP standard — requests, urllib3, il client Http standard in Java, lo stack TLS integrato di Node.js — formano un ClientHello completamente diverso, perché utilizzano OpenSSL o un'altra libreria in modo diverso rispetto a un browser.

È per questo che puoi connetterti a un IP residenziale "pulito", inserire un User-Agent aggiornato di Chrome reale — e comunque ricevere un blocco. Il server vede l'IP dell'utente da un'abitazione, vede l'intestazione "Chrome 124", ma il TLS-handshake dice: "questo è uno script Python". La discrepanza è un segnale diretto per l'anti-bot.

Come i sistemi anti-bot identificano il parser tramite JA3/JA4

Per trasformare i parametri del ClientHello in un identificatore compatto viene utilizzato l'algoritmo JA3 (e la sua versione più recente JA4). Esso prende la versione TLS, l'elenco delle cifrature, delle estensioni e delle curve, li concatena in una stringa e li hash tramite MD5. Si ottiene un breve hash del tipo 769,47-53-5-10...,0-23-65281...,29-23-24,0, che identifica in modo univoco il "fingerprint" del client.

I fornitori di anti-bot (Cloudflare, Akamai, PerimeterX, DataDome — e i loro analoghi utilizzati da Wildberries e Ozon) mantengono database di JA3/JA4 hash noti per librerie HTTP popolari: requests, aiohttp, Scrapy, Node fetch, Java HttpClient, Go net/http. Se l'hash corrisponde a una firma nota di "script", e non a quella di Chrome/Firefox/Safari — la richiesta viene contrassegnata come sospetta ancor prima dell'analisi del comportamento.

Successivamente, il sistema controlla la corrispondenza del TLS-fingerprint con l'User-Agent dichiarato. Se nelle intestazioni è scritto "Chrome 124 su Windows", e il TLS-fingerprint corrisponde a OpenSSL 1.1.1 della libreria standard di Python — questo è chiamato TLS/HTTP mismatch, uno dei segnali più affidabili per il rilevamento dell'automazione. È così che vengono identificati i parser anche con un IP residenziale perfetto e intestazioni corrette.

Come controllare il proprio TLS-fingerprint: strumenti

Prima di risolvere il problema, è necessario vedere cosa vede il server. Ci sono diversi servizi pubblici che mostrano il tuo JA3/JA4 hash e l'intero insieme di parametri del ClientHello:

  • tls.peet.ws — mostra JA3, JA4, l'elenco delle cifrature e delle estensioni in formato JSON, comodo per il controllo automatico tramite script.
  • ja3er.com — database di JA3 hash noti associati a librerie e browser specifici.
  • browserleaks.com/tls — confronto visivo del tuo fingerprint con quelli tipici dei browser.
  • Wireshark localmente — se vuoi vedere il pacchetto grezzo ClientHello durante l'invio della richiesta dal tuo script.

Il test pratico è semplice: apri tls.peet.ws in un normale Chrome e annota l'hash JA4. Poi invia una richiesta GET allo stesso indirizzo dal tuo parser (tramite requests, curl_cffi o qualsiasi altra libreria) attraverso lo stesso proxy e confronta gli hash. Se sono diversi — il server vede la differenza tra "browser" e "script" ad ogni richiesta, indipendentemente da quanto sia pulito l'IP.

Controllo in Python: requests, httpx, curl_cffi

Analizziamo nella pratica perché le librerie standard di Python rivelano il parser. Una richiesta normale tramite requests:

import requests

resp = requests.get("https://tls.peet.ws/api/all", proxies={
    "https": "http://user:pass@proxy_host:port"
})
print(resp.json()["tls"]["ja4"])
# Il risultato sarà diverso dal JA4 di un vero Chrome,
# poiché requests utilizza il modulo ssl standard di Python

Il problema è che requests e httpx utilizzano OpenSSL di sistema tramite il modulo ssl, e l'ordine e l'insieme delle estensioni TLS sono rigidamente fissati e non corrispondono a Chrome/Firefox. La soluzione è la libreria curl_cffi, che utilizza curl patchato con profili TLS reali dei browser:

from curl_cffi import requests as cffi_requests

resp = cffi_requests.get(
    "https://tls.peet.ws/api/all",
    impersonate="chrome124",
    proxies={"https": "http://user:pass@proxy_host:port"}
)
print(resp.json()["tls"]["ja4"])
# L'hash sarà identico a quello di un vero Chrome 124 su desktop

Il parametro impersonate costringe curl_cffi a riprodurre non solo il ClientHello, ma anche l'ordine delle intestazioni HTTP/2 (frame order), che fa parte del fingerprint. Un approccio simile viene utilizzato dalle librerie tls-client per Go e undetected-chromedriver per chi esegue il parsing tramite un vero browser, e non tramite un client HTTP.

Se il parsing avviene tramite un browser headless (Playwright, Puppeteer, Selenium), il TLS-fingerprint viene generato dal motore Chromium/Firefox e di default corrisponde a quello di un vero browser. Ma qui sorge un altro problema: le firme di automazione a livello JS (webdriver flags, canvas fingerprint), quindi per gli scenari headless sono necessari anche patch come playwright-stealth.

TLS + HTTP/2 + intestazioni: perché la combinazione è importante

Il TLS-fingerprint è solo uno strato di rilevamento. I sistemi anti-bot confrontano diversi livelli contemporaneamente:

  • TLS ClientHello (JA3/JA4) — insieme di cifrature ed estensioni.
  • HTTP/2 fingerprint — ordine delle pseudo-intestazioni (:method, :path, :authority), impostazioni del frame SETTINGS, dimensione della finestra.
  • Intestazioni HTTP — ordine e insieme delle intestazioni comuni (Accept-Language, Sec-Ch-Ua, Sec-Fetch-*).
  • User-Agent — deve corrispondere alla versione del profilo TLS: se UA dice "Chrome 124", ma il TLS corrisponde a Chrome 110, è comunque sospetto.

Un errore comune è aggiornare l'User-Agent all'ultima versione di Chrome, dimenticando di aggiornare il profilo TLS in curl_cffi o in un'altra libreria. Questa discrepanza di versioni è visibile all'anti-bot tanto chiaramente quanto l'assenza totale di mascheramento. Controlla che la versione impersonate e la versione nell'User-Agent corrispondano, e aggiorna entrambi i parametri in modo sincronizzato quando vengono rilasciate nuove versioni del browser.

Un altro aspetto è l'ordine delle intestazioni. Il browser invia le intestazioni in un ordine rigorosamente definito, mentre molte librerie HTTP le ordinano in ordine alfabetico o in base all'ordine di aggiunta nel codice. Anche se l'insieme delle intestazioni è identico a quello del browser, un ordine errato è un segnale aggiuntivo per sistemi anti-bot avanzati come DataDome.

Il ruolo dei proxy: perché un IP pulito non basta

L'IP residenziale risolve un compito specifico — riduce la sospettosità in base alla geografia, ASN e reputazione dell'indirizzo. Gli IP dei data center sono spesso in blacklist, perché da essi proviene un traffico automatizzato massivo, mentre gli IP residenziali appartengono a veri fornitori e utenti comuni. Per il parsing di Wildberries, Ozon o Avito questo è critico: senza un IP pulito, la richiesta viene bloccata solo per questo motivo, senza nemmeno controllare il TLS.

Ma l'IP e il TLS-fingerprint sono due strati di protezione indipendenti, e risolvono problemi diversi. L'IP dice al server "da dove" è arrivata la richiesta, il TLS-fingerprint dice "con cosa" è stata inviata. Pertanto, la combinazione di un IP pulito e di un profilo TLS corretto è il minimo necessario per un parsing stabile. Per compiti con alta frequenza di richieste e anti-bot aggressivo, è meglio utilizzare proxy residenziali, che offrono una bassa percentuale di ban per reputazione IP, ma devono essere combinati con una libreria che riproduce correttamente il profilo TLS di un vero browser.

Per il monitoraggio dei prezzi sui marketplace, dove la velocità e il volume delle richieste sono importanti, si utilizzano spesso proxy dei data center in combinazione con mascheramento TLS tramite curl_cffi — è più economico rispetto ai residenziali ed è abbastanza efficace, se il sistema anti-bot del sito non è troppo aggressivo. E per compiti in cui il sito controlla attivamente le reti mobili (ad esempio, il parsing delle versioni mobili delle applicazioni tramite API), si utilizzano proxy mobili — forniscono un ulteriore livello di fiducia grazie alla reputazione delle reti degli operatori.

Checklist per configurare il parser senza rilevamento

Raccogli i controlli in un unico processo prima di avviare il parser in produzione:

  1. Misura l'hash JA4 del tuo script tramite tls.peet.ws e confrontalo con un vero browser della stessa versione.
  2. Utilizza una libreria con supporto per l'imitazione TLS: curl_cffi (Python), tls-client (Go), CycleTLS (Node.js).
  3. Sincronizza la versione del profilo TLS (impersonate) con la versione nell'User-Agent.
  4. Controlla l'ordine delle intestazioni HTTP — deve corrispondere a quello di un vero browser, non a quello alfabetico.
  5. Collegati a un IP residenziale o mobile pulito in base alla geografia del tuo compito.
  6. Configura la rotazione degli IP separatamente dal profilo TLS — non legare rigidamente uno all'altro.
  7. Aggiorna regolarmente il profilo TLS quando vengono rilasciate nuove versioni di Chrome — le vecchie firme finiscono nei database degli anti-bot più velocemente di quanto sembri.
  8. Per scenari con controlli JS (Cloudflare Challenge) utilizza un browser headless con patch stealth invece di un semplice client HTTP.

Confronto tra librerie e strumenti

Strumento TLS-fingerprint del browser Velocità Quando utilizzare
requests / httpx No, restituisce uno script Alta Siti senza rilevamento TLS, API interne
curl_cffi Sì, copia esatta Alta Marketplace, anti-bot Cloudflare/Akamai
tls-client (Go) Sì Molto alta Carico elevato, parsing massivo
Playwright / Puppeteer Sì, motore reale Bassa JS-render, Cloudflare Challenge, SPA complesse
Scrapy (standard) No Alta Siti senza protezione anti-bot rigorosa

Conclusione

Il TLS-fingerprint è uno strato di protezione che molti parser ignorano completamente, spendendo risorse per trovare l'IP e l'User-Agent perfetti, ma dimenticando che la stessa struttura del TLS-handshake rivela l'automazione prima che il server guardi le intestazioni. La soluzione è utilizzare librerie con supporto per l'imitazione TLS (curl_cffi, tls-client), sincronizzare la versione del profilo con l'User-Agent e controllare l'hash JA4 finale prima di avviare il parsing su larga scala.

L'IP rimane comunque un fattore importante — senza un indirizzo pulito, anche il TLS-fingerprint perfetto non aiuterà a superare il blocco per reputazione di rete. Per il parsing dei marketplace e il monitoraggio dei prezzi, è ragionevole combinare la corretta configurazione TLS con proxy residenziali — questa combinazione chiude entrambi gli strati di rilevamento e riduce notevolmente la percentuale di ban durante le lunghe sessioni di parsing.