Akamai Bot Manager è una delle soluzioni anti-bot più comuni sul mercato. È utilizzato da molti siti web di alto profilo, dai siti di e-commerce ai siti di viaggio, e, a seconda della sua configurazione, può essere difficile da bypassare. Sulla base della mia esperienza, il modello tipico che incontro quando un sito web attiva la protezione di Akamai Bot Manager è che il raschiatore (di solito uno Scrapy nella mia pila) si appende e si estingue dalla prima richiesta. Ma cosa è Akamai Bot Manager, e come posso vedere se un sito web lo sta utilizzando? Akamai Bot Manager Visualizzazione generale La rilevazione dei bot di Akamai, come ogni altro software moderno di protezione anti-bot, funziona su più strati. è uno dei primi: Akamai analizza i dettagli della mano e della connessione TLS (impronta digitale TLS JA3, suite di cifratura, versione TLS, ecc.) per vedere se corrispondono a un browser reale o a uno strumento di automazione noto. Ogni browser (Chrome, Firefox, Safari, ecc.) ha una impronta digitale TLS caratteristica, e se il tuo client TLS Client Hello non corrisponde a un browser comune, Akamai sa che c'è qualcosa di pesante. Network fingerprinting Esaminano anche – I browser reali utilizzano quasi sempre HTTP/2+ in questi giorni, e inviano intestazioni HTTP in un certo ordine e formato. Se un client utilizza ancora HTTP/1.1 o ha intestazioni in un ordine non browser, è una bandiera rossa. Inoltre, Akamai cerca intestazioni specifiche del browser o valori che i raschiatori potrebbero omettere; assicurando i tuoi intestazioni (User-Agent, Accept-Language, ecc.) Lo specchio di un vero browser è fondamentale. HTTP/2 usage and header order and their order Un altro layer è Akamai verifica se l'IP del client proviene da una rete residenziale, da una rete mobile o da un datacenter. Gli IP residenziali e mobili (il tipo di utenti reali) hanno un punteggio elevato sulla fiducia, mentre i ranghi IP del datacenter conosciuti sono automaticamente sospetti. - appaiono sempre provenienti da diverse posizioni degli utenti reali, non da una fattoria di server cloud. IP reputation and analysis residential proxies Alla fine, Un sensore JavaScript sulla pagina web raccoglie una moltitudine di punti di dati sull'ambiente e le interazioni del cliente (come il timing, i movimenti del mouse, o la loro assenza, proprietà insolite nell'oggetto del browser, ecc.).I modelli AI di Akamai crunch questi dati per assegnare un punteggio di probabilità bot a ogni sessione.Questo aspetto è il più difficile da bypassare e spesso richiede di eseguire un browser senza testa o replicare la logica del sensore. (È al di là del nostro ambito qui - il nostro focus sarà passare i controlli a livello di rete, che è il caso più comune per i siti web di e-commerce, nella mia esperienza.) Il lavoro di Akamai analisi comportamentale Utilizzo di script client-side e modelli AI Il lavoro di Akamai analisi comportamentale analisi comportamentale Utilizzo di script client-side e modelli AI Ma come possiamo rilevare che un sito web utilizza Akamai Bot Manager? Oltre a Se si nota il e cookie utilizzati su un sito web, questo è il segno più chiaro che sta utilizzando Akamai per proteggersi. La solita estensione del browser Wappalyzer - Abc di bmsc La solita estensione del browser Wappalyzer - Abc - Abc di bmsc di bmsc A causa di queste difese, molti utenti di Scrapy si sono rivolti al download manager per bypassare Akamai. Questo plugin integra il Libreria per impersonare le firme di rete dei browser reali. scrapy-impersonate curl_cffi In pratica, Scrapy Impersonate rende le richieste del tuo Scrapy spider "aspetto" come un Chrome o Firefox: offre impronte digitali TLS (JA3) che corrispondono a quei browser, utilizza HTTP/2, e addirittura regola gli intestazioni di frame HTTP/2 a basso livello per imitare i modelli del browser. In questo modo, risolve il problema delle impronte digitali TLS e HTTP/2 - un Scrapy spider con questo gestore può agire con un server protetto da Akamai in modo quasi indistinguibile da un normale browser Chrome. I limiti di Scrapy Impersonate Mentre Scrapy Impersonate è uno strumento potente, viene fornito con alcune limitazioni: Scrapy Impersonate is designed as a Scrapy download handler, which means it only works within Scrapy’s asynchronous framework. If your project doesn’t use Scrapy or you want to switch to a different framework (like a simple script with / or an asyncio pipeline), you can’t directly carry over its capabilities. Migrating away from Scrapy often means a of your HTTP logic, and you’d lose the built-in TLS spoofing unless you implement a new solution from scratch. Locked into Scrapy: requests httpx complete rewrite Using Scrapy Impersonate alongside proxy rotation can be tricky. Under the hood, it replaces Scrapy’s default downloader with one based on , which doesn’t seamlessly integrate with Scrapy’s proxy middleware. Early adopters discovered that HTTPS proxy support was broken because the proxy handling code was bypassed. Although fixes and workarounds (like disabling Scrapy’s built-in proxy handling and configuring directly) exist, it’s harder to rotate proxies or handle proxy authentication with this setup. Robust error handling for proxy failures (e.g., detecting a dead proxy and retrying) is not as straightforward as with Scrapy’s standard downloader, because errors bubble up from the layer and may not trigger Scrapy’s usual retry logic. Proxy Rotation Challenges: curl_cffi curl_cffi curl Scrapy Impersonate currently supports a finite list of browser fingerprints (Chrome, Edge, Safari, etc., up to certain versions). This list can lag behind the latest browser releases. You might be stuck impersonating an older browser version, which could be a problem if a target site specifically requires the nuances of a newer TLS handshake (some advanced WAFs actually check minor details that change between Chrome versions). Maintenance and Flexibility: Perhaps most importantly, even with proper TLS and HTTP/2 impersonation, . For websites that have implemented a higher level of protection, checking also the browser fingerprint, any browserless configuration, including Scrapy Impersonate, isn’t sufficient for Akamai or similar top-tier bot defenses. You might get past the TLS handshake, but fail on other signals (like the absence of the expected sensor data or subtle discrepancies in headers/cookies). In other words, it’s a piece of the puzzle, not a complete solution. Not a Silver Bullet: Akamai Bot Manager can still detect and block you La soluzione che vedremo oggi aiuta a risolvere i primi due punti: ci uniremo , per un'impronta digitale TLS ottimale e un proxy residenziale rotante per ruotare i nostri IP e avere punteggi di reputazione più alti. 3 Proxy 3 Proxy Comprensione delle impronte digitali TLS e JA3 Prima di immergersi nella soluzione, è importante capire esattamente cosa stiamo falsificando. Ogni client HTTPS presenta un Questa impronta digitale è una combinazione della versione del protocollo TLS e di un sacco di opzioni che il client afferma di supportare – pensa a questo come al “dialetto” del client di parlare TLS. I componenti chiave includono: TLS fingerprint e.g. TLS 1.2 vs TLS 1.3. Modern browsers will offer 1.3 (while still allowing 1.2 for compatibility). Older clients or some libraries might only do 1.2. Supported TLS Version: the list of cryptographic algorithms the client can use, in preferred order. Browsers tend to have long lists including ciphers like AES-GCM, ChaCha20, etc., plus some GREASE (randomized) values to prevent fingerprinting. Cipher Suites: extra features in TLS, like Server Name Indication (SNI), supported groups (elliptic curves), ALPN (which is used for HTTP/2 negotiation), etc. Both the presence of certain extensions and their order matter. Extensions: Il concetto di è un modo standardizzato per registrare questi dettagli TLS Client Hello. JA3, chiamato dopo le iniziali dei suoi creatori, compone una stringa di impronte digitali concatenando i campi di cui sopra in un ordine specifico: JA3 fingerprinting JA3_string = TLSVersion,CipherSuiteIDs,ExtensionIDs,EllipticCurveIDs,EllipticCurveFormatIDs Ogni elenco (numeri, estensioni, ecc.) è unito da Le sezioni di Ad esempio, un browser Chrome potrebbe produrre una stringa JA3 come: - , 771,4866-4867-4865-....-47-255,0-11-10-16-23-...-21,29-23-30-25-24,0-1-2 Questo rappresenta TLS 1.2 (771 è 0x0303), un set specifico di suite di cifratura, estensioni, curve supportate e formati di curva (i numeri sono ID standardizzati). Gli strumenti di sicurezza spesso registrano o confrontano il hash MD5 (poiché è più facile da gestire rispetto a una lunga stringa di numeri). MD5 hashed Perché questo è importante per la rilevazione bot? perché Chrome versione X su Windows presentare la stessa impronta digitale JA3 all'ordine dell'elenco. Firefox avrà il proprio JA3 distinto. browser TLS stacks are fairly uniform sempre La libreria di richieste di Python (che utilizza OpenSSL sotto il cappello) ha un JA3 che è completamente diverso da qualsiasi browser mainstream, quindi è facilmente rilevabile. I servizi anti-bot come Akamai mantengono database di hash di JA3: se il tuo JA3 non è nell'elenco dei "buoni noti" (browser comuni) o se si trova in una lista di automazione nota, sarai segnalato. In sintesi, per superare i controlli delle impronte digitali TLS di Akamai, . we need our client’s JA3 to match a popular browser Questo di solito significa imitare l'ultima impronta digitale di Chrome o Firefox (poiché questi sono gli utenti legittimi più comuni sul web). Semplicemente cambiare la stringa User-Agent non è sufficiente – dobbiamo modificare il manoscritto TLS a basso livello. (che da sola sfrutta una speciale costruzione di librerie curl e TLS per imitare i browser). ma al di fuori di Scrapy, abbiamo bisogno di un altro modo per raggiungere lo stesso effetto. curl_cffi TLS Impersonation Proxy + Rete Proxy Residenziale La nostra soluzione è quella di per rendere il nostro raschiatore praticamente indistinguibile da un vero utente del browser: chain two proxies JA3Proxy is an open-source tool that acts as an HTTP(S) proxy that replays traffic with a chosen TLS fingerprint. In other words, you run JA3Proxy locally, configure it to imitate a specific browser’s TLS handshake, and then direct your scraper traffic through it. JA3Proxy will terminate your TLS connection and initiate a new TLS handshake to the target site using the impersonated fingerprint. From the target site’s perspective, it looks like, say, a Chrome browser connecting. The beauty of this approach is that – you can use Python , , cURL, or anything, by simply pointing it at JA3Proxy. You are no longer locked into Scrapy or any particular library to get browser-like TLS; the proxy takes care of it. JA3Proxy for TLS Impersonation: it’s client-agnostic requests httpx Under the hood, JA3Proxy uses (an advanced TLS library in Go) to customize the Client Hello. It supports a variety of client profiles (Chrome, Firefox, Safari, etc., across different versions). You can, for example, configure it to mimic the latest browsers available in the library. For our needs, we’d choose the latest available Chrome fingerprint, Chrome 133. As for Scrapy-Impersonate, the integration of the latest browsers in the library can take some time, but until this gets regularly updated, it’s not an issue. uTLS One thing to note: JA3Proxy focuses on TLS fingerprints (the JA3 part). It doesn’t inherently modify HTTP headers (other than those that relate to TLS, like ALPN for HTTP/2) or handle higher-level browser behaviors. It gets us past the network fingerprinting, which is the hardest to change, but we must still ensure our HTTP headers and usage patterns are correct. Luckily, we can manually set headers in our HTTP client to mimic a browser (User-Agent, etc.), and HTTP/2 can be achieved as long as the TLS negotiation allows it (Chrome’s Client Hello will advertise ALPN support for h2, so if the site supports it, JA3Proxy will negotiate HTTP/2). The second part of the chain is an upstream . This will take care of the IP reputation and distribution. Residential Proxy for IP Rotation: residential proxy The combined effect is powerful: to Akamai, your scraper now looks like Chrome 133 running on a residential IP. The TLS handshake matches Chrome’s JA3, the HTTP/2 and headers can be adjusted to match Chrome, and the source IP is a regular household. This addresses the major fingerprinting vectors at the network level. It doesn’t solve Akamai’s JavaScript-based challenges by itself, but this should be enough to bypass most of the websites you’ll encounter. Guida di installazione per JA3Proxy Possiamo configurare JA3Proxy e collegarlo con un proxy residenziale. Installazione di JA3Proxy JA3Proxy è scritto in Go. Hai due opzioni semplici: compilare dalla fonte o usare un contenitore Docker. Per costruire dalla fonte, avrai bisogno di Go installato. Eseguire: git clone https://github.com/LyleMi/ja3proxy.git cd ja3proxy make Questo dovrebbe produrre un eseguibile nella cartella. (Alternativamente, è possibile eseguire manualmente dal momento che il progetto è basato su Go.) ja3proxy go build Se preferisci Docker, c'è un'immagine prefabbricata nel registro dei container di GitHub. docker pull ghcr.io/lylemi/ja3proxy:latest visualizzerà l'immagine più recente. Puoi quindi eseguirla con (Stiamo mostrando il comando di eseguire in un attimo.) Docker è conveniente perché pacchetta tutto senza bisogno di un ambiente Go locale. docker run Nella mia esperienza personale, l'installazione è stata un po' un incubo. Non sono stato in grado di far funzionare l'immagine Docker, poiché ho ricevuto costantemente errori quando ho cercato di connettermi a esso, poiché nessun browser è stato riconosciuto. Poi ho deciso di costruire manualmente sul mio Mac, e ho incontrato gli stessi errori. Tuttavia, dopo ore di debugging, ho scoperto che avevo bisogno di aggiornare alcune dipendenze, specialmente uTLS; c'erano conflitti nelle versioni delle librerie, e tutto questo stava causando problemi. Ottenere o creare certificati TLS JA3Proxy può agire come un proxy HTTPS, il che significa che intercetta TLS e presenta il proprio certificato al tuo client. Per impostazione predefinita, si cerca e Se non ne fornisci uno, potresti eseguirlo in modalità semplice (come un proxy HTTP normale) e semplicemente ignorare la verifica del certificato nel tuo client (non raccomandato per la produzione, ma accettabile per il test). cert.pem key.pem La migliore pratica è quella di generare un certificato root e una chiave auto-signate, e configurare il raschiatore per fidarsi di quel certificato, in modo da poter intercettare il traffico senza avvisi di sicurezza. openssl req -x509 -newkey rsa:2048 -sha256 -days 365 -nodes -keyout key.pem -out cert.pem -subj "/CN=JA3Proxy" Questo crea a / (Per l'uso di produzione, potresti persino utilizzare un CA interno legittimo se hai quella configurazione, ma per la maggior parte delle finalità di raschiamento, un auto-signato è buono purché il tuo cliente sappia fidarsi di esso.) cert.pem key.pem Avviare JA3Proxy con un'impronta digitale di Chrome Ora eseguiamo il proxy. Se si usa il binario, esegui un comando come: ./ja3proxy -port 8080 -client Chrome -version 131 -cert cert.pem -key key.pem -upstream YOURPROXYIP:PORT Combattiamo questo comando: - la porta 8080 gli dice di ascoltare la porta 8080 (si può scegliere un'altra porta se necessario). -client Chrome -versione 131 seleziona il profilo di impronte digitali. In questo esempio, utilizza il profilo integrato per Chrome 131. Le sostituiresti con il profilo corrispondente al browser/versione desiderata – ad esempio, se Chrome 130 è supportato nell'ultima versione, potresti utilizzare -client Chrome -versione 130. (Puoi trovare l'elenco delle impronte digitali disponibili controllando la documentazione di JA3Proxy o la libreria uTLS che utilizza. -cert e -key specificano i file del certificato TLS che abbiamo generato nel passaggio 2. -upstream 123.45.67.89:1080 è l'indirizzo del proxy upstream. Questo dovrebbe essere sostituito con il tuo terminale proxy residenziale. Importante: JA3Proxy si aspetta che questo sia un indirizzo proxy SOCKS5__github.com__. Se il tuo provider ti ha dato qualcosa come proxy.provider.com:8000 con un nome utente/password, puoi provare il formato username:password@proxy.provider.com:8000. (JA3Proxy analizzerà la stringa e dovrebbe gestire l'autenticazione per SOCKS5 se dato nel modulo user:pass@host:port. Se questo non funziona, potresti configurare il tuo proxy residenziale per essere IP-permesso o utilizzare una funzionalità di whitelist IP per evitare auth, o esegu Se si utilizzasse Docker, l’equivalente sarebbe: docker run -p 8080:8080 \ -v $(pwd)/cert.pem:/app/cert.pem -v $(pwd)/key.pem:/app/key.pem \ ghcr.io/lylemi/ja3proxy:latest \ -client Chrome -version 133 -cert /app/cert.pem -key /app/key.pem \ -upstream YOURPROXYIP:PORT Montiamo il cert e la chiave nel contenitore e esponiamo il port 8080. Regola il comando per includere le credenziali proxy/host reali. (o qualsiasi host/port specificato da voi). localhost:8080 Un caso di utilizzo del mondo reale - MrPorter.com MrPorter.com è un sito di e-commerce di moda che, insieme a molti altri nel settore, si protegge con Akamai Bot Manager. Utilizzando una semplice richiesta Python, come specificato nel file nel repository, ho incontrato un errore di timeout, come previsto. simple_request.py import requests URL = "https://www.mrporter.com/en-gb/mens/product/loewe/clothing/casual-shorts/plus-paula-s-ibiza-wide-leg-printed-cotton-blend-terry-jacquard-shorts/46376663162864673" headers = { "accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8", "accept-language": "en-US,en;q=0.5", "priority": "u=0, i", "sec-ch-ua": "\"Brave\";v=\"135\", \"Not-A.Brand\";v=\"8\", \"Chromium\";v=\"135\"", "sec-ch-ua-mobile": "?0", "sec-ch-ua-platform": "\"macOS\"", "sec-fetch-dest": "document", "sec-fetch-mode": "navigate", "sec-fetch-site": "none", "sec-fetch-user": "?1", "sec-gpc": "1", "service-worker-navigation-preload": "true", "upgrade-insecure-requests": "1", "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/135.0.0.0 Safari/537.36" } def main(): try: response = requests.get(URL, headers=headers, timeout=10) response.raise_for_status() print(response.text) except requests.RequestException as e: print(f"Error fetching the page: {e}") if __name__ == "__main__": main() Risultato : Error fetching the page: HTTPSConnectionPool(host='www.mrporter.com', port=443): Read timed out. (read timeout=10) Con l’utilizzo di Tuttavia, non sono stato in grado di trovare un database che indica che le richieste di Python usano comunemente questa impronta digitale. Sicuramente, è diverso dall'impronta digitale che ho ottenuto usando Brave Browser, con gli stessi intestazioni e User Agent. Scrapfly TLS Strumento per le impronte digitali we can view the results Scrapfly TLS Strumento per le impronte digitali Possiamo vedere i risultati L'ordine delle Cipher Suites è diverso, e quindi anche l'impronta digitale sarà diversa. Ora, avviamo il docker JA3Proxy, senza collegare un proxy residenziale, e vediamo cosa succede. docker run -p 8080:8080 \ -v $(pwd)/cert.pem:/app/cert.pem -v $(pwd)/key.pem:/app/key.pem \ ghcr.io/lylemi/ja3proxy:latest \ -client Chrome -version 131 -cert /app/cert.pem -key /app/key.pem Abbiamo ricevuto il messaggio HTTP Proxy Server listen at :8080, with tls fingerprint 131 Chrome Così possiamo usare localhost:8080 come proxy nel nostro script di richiesta di Python. Un'altra causa di errori nella mia configurazione era che ho provato a utilizzare Python Requests per connettermi a JA3Proxy. Dopo aver scavato per un po ', ho scoperto che il problema era che la libreria di richieste non supporta HTTP/2, mentre JA3Proxy lo fa quando si utilizza una versione moderna di Chrome. Per i miei test, ho bisogno di utilizzare HTTPX, come mostrato nel file . request_with_proxies.py In questo caso, se chiamo nuovamente l'API Scrapfly TLS, la prima parte della stringa JA3 (l'ordine Cipher) . è identico a quello del mio browser è identico a quello del mio browser Come prova finale, se utilizziamo questo script per richiedere la pagina MrPorter, possiamo scaricarla senza alcun problema. Creazione di un proxy residenziale Ora che abbiamo risolto la falsificazione dell'impronta digitale TLS, abbiamo solo bisogno di ruotare l'IP che il sito di destinazione vedrà. JA3Proxy ha un'opzione che ci aiuta in questo, chiamato upstream. Avviando il comando JA3Proxy come segue, ./ja3proxy -addr 127.0.0.1 -client Chrome -version 131 -cert cert.pem -key key.pem -upstream socks5h://USER:PASS@PROVIDER:PORT -debug siamo in grado di tunelare le nostre richieste utilizzando il nostro provider proxy preferito. Si prega di notare che è necessario connettersi tramite SOCKS5, quindi assicurarsi che il tuo provider supporti questa funzione. Controllando l'IP dopo aver fatto questo, posso vedere che le mie IP di rotazione residenziale sono in posizione, e posso continuare a scaricare pagine MRPorter senza problemi. pierluigivinciguerra@Mac 85.AKAMAI-JA3PROXY % python3.10 request_with_proxies.py 200 {"ip":"5.49.222.37"} pierluigivinciguerra@Mac 85.AKAMAI-JA3PROXY % python3.10 request_with_proxies.py 200 {"ip":"197.244.237.29"} pierluigivinciguerra@Mac 85.AKAMAI-JA3PROXY % python3.10 request_with_proxies.py 200 {"ip":"41.193.144.67"} pierluigivinciguerra@Mac 85.AKAMAI-JA3PROXY % python3.10 request_with_proxies.py 200 {"ip":"102.217.240.216"} pierluigivinciguerra@Mac 85.AKAMAI-JA3PROXY % python3.10 request_with_proxies.py Conclusioni In questo post, abbiamo visto come bypassare il Akamai Bot Manager sul sito web MrPorter.Il livello di protezione del sito web è medio, quindi non c'è sfida di impronte digitali complesse da bypassare, ma, nella mia esperienza, è il caso d'uso più comune quando incontriamo Akamai sulla nostra strada. Ho scelto di seguire l'approccio JA3Proxy per bypassarlo, in modo che questa soluzione possa essere utilizzata in vari framework. Se stai usando Scrapy, puoi sempre fare affidamento su Scrapy Impersonate, nonostante le sue limitazioni, o puoi provare a impostare le cifre nell'ordine corretto manualmente. L'articolo fa parte della serie "The Lab" di Pierluigi Vinciguerra. Consulta la sua pagina Substack per ulteriori conoscenze sul Web Scraping. L’articolo fa parte di serie di Controllare il suo pagina per maggiori conoscenze su Web Scraping. “The Lab” di Pierluigi Vinciguerra Sostanza “Il laboratorio”