Akamai Bot Manager is een van de meest voorkomende anti-bot-oplossingen op de markt. Het wordt gebruikt door veel hooggeprofileerde websites, variërend van e-commerce-sites tot reiswebsites, en, afhankelijk van de configuratie, kan het moeilijk zijn om te omzeilen. Op basis van mijn ervaring is het typische patroon dat ik tegenkom wanneer een website Akamai Bot Manager-bescherming activeert, dat de scraper (meestal een Scrapy in mijn stack) hangt en tijden uit van de eerste aanvraag. Maar wat is Akamai Bot Manager, en hoe kan ik zien of een website het gebruikt? Akamai Bot Manager Overzicht Akamai's botdetectie, net als elke andere moderne anti-bot bescherming software, werkt op meerdere lagen. is een van de eerste: Akamai analyseert de TLS handshake en verbinding details (JA3 TLS vingerafdrukken, encryptie suites, TLS versie, etc.) om te zien of ze overeenkomen met een echte browser of een bekende automatisering tool. Network fingerprinting Het inspecteert ook – echte browsers gebruiken tegenwoordig bijna altijd HTTP/2+ en ze sturen HTTP-koppen in een bepaalde volgorde en formaat. als een client nog steeds HTTP/1.1 gebruikt of koppen in een niet-browser volgorde heeft, is het een rode vlag. Spiegel van een echte browser is cruciaal. HTTP/2 usage and header order and their order Een andere layer is Akamai controleert of de client-IP afkomstig is van een residentiële netwerk, mobiel netwerk of datacenter. Residentiële en mobiele IP's (de soort echte gebruikers hebben) scoren hoog op vertrouwen, terwijl bekende datacenter-IP-bereiken automatisch verdacht zijn. – altijd te lijken afkomstig te zijn van verschillende echte gebruikerslocaties, niet van een cloud serverfarm. IP reputation and analysis residential proxies Ten slotte Een JavaScript-sensor op de webpagina verzamelt een verscheidenheid aan gegevenspunten over de omgeving en interacties van de client (zoals timing, muisbewegingen of hun afwezigheid, ongewone eigenschappen in het browserobject, enz.).Akamai's AI-modellen crunch deze gegevens om een bot waarschijnlijkheidsscore toe te wijzen aan elke sessie.Dit aspect is het moeilijkste om te omzeilen en vereist vaak het uitvoeren van een hoofdloze browser of het repliceren van de sensorlogica. Akamai werkgelegenheid Gedragsanalyse Het gebruik van client-side scripts en AI-modellen Akamai werkgelegenheid Gedragsanalyse Gedragsanalyse Het gebruik van client-side scripts en AI-modellen Maar hoe kunnen we detecteren dat een website Akamai Bot Manager gebruikt? Behalve van Als u opmerkt dat de en Cookies die op een website worden gebruikt, dit is het duidelijkste teken dat het Akamai gebruikt om zichzelf te beschermen. De gebruikelijke Wappalyzer browser extensie - Abc met bmsc De gebruikelijke Wappalyzer browser extensie - Abc - Abc met bmsc met bmsc Gezien deze verdedigingen hebben veel Scrapy-gebruikers zich tot de download manager om Akamai te omzeilen. Deze plugin integreert de bibliotheek om te doen alsof echte browsers 'netwerk handtekeningen. scrapy-impersonate curl_cffi In de praktijk maakt Scrapy Impersonate de verzoeken van uw Scrapy spider "look" als een Chrome of Firefox: het biedt TLS vingerafdrukken (JA3) die overeenkomen met die browsers, maakt gebruik van HTTP/2, en zelfs regelt lage HTTP/2 frame headers om de patronen van de browser na te bootsen. Beperkingen van Scrapy Impersonate Hoewel Scrapy Impersonate een krachtig hulpmiddel is, heeft het bepaalde beperkingen: 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 De oplossing die we vandaag zullen zien helpt bij het oplossen van de eerste twee punten: we zullen samen ketenen , voor een optimale TLS vingerafdruk en een roterende residentiële proxy om onze IP's te roteren en hogere reputatiescores te hebben. Ja3Proxy Ja3Proxy TLS vingerafdrukken en JA3 Voordat je in de oplossing duikt, is het belangrijk om te begrijpen wat we precies misleiden.Elke HTTPS-client presenteert een unieke Deze vingerafdruk is een combinatie van de versie van het TLS-protocol en een reeks opties die de client zegt te ondersteunen - denk er dan aan als de "dialect" van de client om TLS te spreken. 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: Het concept van is een gestandaardiseerde manier om deze TLS Client Hello-gegevens op te nemen. JA3, vernoemd naar de initialen van de makers, maakt een vingerafdrukreeks samen door de bovenstaande velden in een specifieke volgorde te verzoenen: JA3 fingerprinting JA3_string = TLSVersion,CipherSuiteIDs,ExtensionIDs,EllipticCurveIDs,EllipticCurveFormatIDs Elke lijst (cijfers, uitbreidingen, enz.) wordt toegevoegd door En de secties van Een Chrome-browser kan bijvoorbeeld een JA3-reeks produceren zoals: - , 771,4866-4867-4865-....-47-255,0-11-10-16-23-...-21,29-23-30-25-24,0-1-2 Dit vertegenwoordigt TLS 1.2 (771 is 0x0303), een specifieke set van cipher suites, extensies, ondersteunde curven en curve formaten (de nummers zijn gestandaardiseerde ID's). Beveiligingshulpmiddelen loggen vaak of vergelijken de MD5-hash (omdat het gemakkelijker te hanteren is dan een lange reeks getallen). MD5 hashed Waarom is dit belangrijk voor botdetectie? omdat Chrome versie X op Windows zal presenteer dezelfde JA3 vingerafdruk naar beneden in de volgorde van de lijst. Firefox heeft zijn eigen onderscheidende JA3. browser TLS stacks are fairly uniform Altijd De verzoekenbibliotheek van Python (die OpenSSL onder de hoed gebruikt) heeft een JA3 die totaal anders is dan elke mainstream browser, dus het is gemakkelijk te detecteren. Anti-bot-services zoals Akamai onderhouden databases van JA3-hashes: als je JA3 niet op de "bekende goede" lijst staat (gewone browsers) of als het op een bekende automatiseringslijst staat, krijg je een vlag. Kortom, om de TLS-vingerafdrukcontroles van Akamai door te geven, . we need our client’s JA3 to match a popular browser Dit betekent meestal het imiteren van de nieuwste Chrome of Firefox vingerafdruk (omdat dit de meest voorkomende legitieme gebruikers op het web zijn). Het veranderen van de User-Agent-reeks is niet voldoende – we moeten de TLS-handshake op een laag niveau wijzigen. (die zelf gebruik maakt van een speciale constructie van curl- en TLS-bibliotheken om browsers te imiteren). curl_cffi TLS Impersonatie Proxy + Residentiële Proxy Chain Onze oplossing is om om onze scraper praktisch niet te onderscheiden van een echte browser-gebruiker: 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. Installatiehandleiding voor JA3Proxy Laten we JA3Proxy instellen en ketenen met een residentiële proxy. Installeer JA3Proxy JA3Proxy is geschreven in Go. Je hebt twee eenvoudige opties: compileer vanuit de bron of gebruik een Docker-container. Om vanuit de bron te bouwen, moet je Go geïnstalleerd hebben. git clone https://github.com/LyleMi/ja3proxy.git cd ja3proxy make Dit zou moeten leiden tot een kan worden uitgevoerd in de map. (Alternatief kunt u handmatig, aangezien het project op Go-gebaseerd is.) ja3proxy go build Als u de voorkeur geeft aan Docker, is er een vooraf gebouwde afbeelding op GitHub Container Registry. docker pull ghcr.io/lylemi/ja3proxy:latest de nieuwste afbeelding. U kunt deze vervolgens uitvoeren met (We zullen de run-opdracht in een moment laten zien.) Docker is handig omdat het alles verpakt zonder dat er een lokale Go-omgeving nodig is. docker run In mijn persoonlijke ervaring was de installatie een beetje een nachtmerrie. Ik was niet in staat om de Docker-afbeelding te laten werken, omdat ik consequent fouten kreeg bij het proberen ermee verbinding te maken, omdat er geen browser werd herkend. Toen besloot ik om handmatig op mijn Mac te bouwen, en ik ontmoette dezelfde fouten. Echter, na uren van debuggen, ontdekte ik dat ik sommige afhankelijkheden moest bijwerken, vooral uTLS; er waren conflicten in de versies van de bibliotheken, en dit alles veroorzaakte problemen. Het verkrijgen of maken van TLS-certificaten JA3Proxy kan fungeren als een HTTPS-proxy, wat betekent dat het TLS onderschept en zijn eigen certificaat aan uw client presenteert. Standaard is het op zoek naar en Als u een certificaat niet verstrekt, kunt u het in eenvoudige tekstmodus uitvoeren (als een reguliere HTTP-proxy) en gewoon certificatenverificatie in uw client negeren (niet aanbevolen voor productie, maar acceptabel voor testen). cert.pem key.pem De beste praktijk is om een zelfondertekend rootcertificaat en sleutel te genereren en uw scraper te configureren om dat certificaat te vertrouwen, zodat u verkeer zonder beveiligingswaarschuwingen kunt onderscheppen. openssl req -x509 -newkey rsa:2048 -sha256 -days 365 -nodes -keyout key.pem -out cert.pem -subj "/CN=JA3Proxy" Dit creëert een / (Voor productiegebruik kunt u zelfs een legitieme interne CA gebruiken als u die instelling hebt, maar voor de meeste scrapingdoeleinden is een zelfondertekend goed zolang uw klant weet het te vertrouwen.) cert.pem key.pem JA3Proxy starten met een Chrome-vingerprint Nu draaien we de proxy. Als u de binaire gebruikt, voert u een opdracht uit zoals: ./ja3proxy -port 8080 -client Chrome -version 131 -cert cert.pem -key key.pem -upstream YOURPROXYIP:PORT Laten we deze opdracht afbreken: -poort 8080 vertelt het om te luisteren op poort 8080 (u kunt een andere poort kiezen als dat nodig is). -client Chrome -versie 131 selecteert het vingerafdrukprofiel. In dit voorbeeld gebruikt het het ingebouwde profiel voor Chrome 131. U zou deze vervangen door het profiel dat overeenkomt met de browser / versie die u wilt - bijvoorbeeld, als Chrome 130 wordt ondersteund in de nieuwste versie, kunt u -client Chrome -versie 130 gebruiken. (U kunt de lijst met beschikbare vingerafdrukken vinden door de documentatie van JA3Proxy te controleren of de uTLS-bibliotheek die het gebruikt. -cert en -key specificeren de TLS-certificaatbestanden die we in stap 2 hebben gegenereerd. -upstream 123.45.67.89:1080 is het adres van de upstream proxy. Dit moet worden vervangen door uw residentiële proxy-eindpunt. Belangrijk: JA3Proxy verwacht dat dit een SOCKS5-proxy-adres is__github.com__. Als uw provider u iets als proxy.provider.com:8000 heeft gegeven met een gebruikersnaam/wachtwoord, kunt u het formaat gebruikersnaam proberen:password@proxy.provider.com:8000. (JA3Proxy zal de string analyseren en moet authenticatie voor SOCKS5 verwerken als het in het user:pass@host:port-formulier wordt gegeven. Als dat niet werkt, kunt u uw residentiële proxy configureren om IP-toegestaan te worden of een IP whitelist-functie gebruiken om auth Als u Docker gebruikt, zou het equivalent zijn: 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 We monteren de cert en de sleutel in de container en onthullen de poort 8080. Pas de opdracht aan om uw werkelijke proxy-credentials/host op te nemen. (of welke host/poort u ook heeft opgegeven). localhost:8080 Een echte gebruikssituatie - MrPorter.com MrPorter.com is een mode e-commerce website die, samen met vele anderen in de industrie, zichzelf beschermt met Akamai Bot Manager. Door een eenvoudige Python-verzoek te gebruiken, zoals gespecificeerd in het bestand In het repository heb ik een timeout-fout geconfronteerd, zoals verwacht. 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() Het resultaat: Error fetching the page: HTTPSConnectionPool(host='www.mrporter.com', port=443): Read timed out. (read timeout=10) Door gebruik - het Ik was echter niet in staat om een database te vinden die aangeeft dat Python-verzoeken vaak deze vingerafdruk gebruiken. Scrapfly TLS vingerafdruksysteem We kunnen de resultaten zien Scrapfly TLS vingerafdruksysteem We kunnen de resultaten zien De volgorde van de Cipher Suites is anders en daarom zal ook de vingerafdruk anders zijn. Laten we nu de JA3Proxy-docker starten, zonder een residentiële proxy aan te sluiten, en zien wat er gebeurt. 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 We kregen de boodschap HTTP Proxy Server listen at :8080, with tls fingerprint 131 Chrome Zo kunnen we localhost:8080 gebruiken als een proxy in ons Python-aanvraag script. Een andere oorzaak van fouten in mijn installatie was dat ik probeerde Python Requests te gebruiken om verbinding te maken met JA3Proxy.Na een tijdje te graven, ontdekte ik dat het probleem was dat de verzoeksbibliotheek HTTP/2 niet ondersteunt, terwijl JA3Proxy dat doet bij het gebruik van een moderne versie van Chrome. Voor mijn tests moet ik HTTPX gebruiken, zoals weergegeven in het bestand . request_with_proxies.py In dit geval, als ik de Scrapfly TLS API opnieuw oproep, het eerste deel van de JA3-reeks (de Cipher-orde) . is identiek aan die van mijn browser is identiek aan die van mijn browser Als laatste test, als we dit script gebruiken om de MrPorter-pagina aan te vragen, kunnen we het zonder problemen downloaden. Een residentiële proxy Nu we de vervalsing van de TLS-vingerafdruk hebben opgelost, moeten we alleen de IP roteren die de doelwebsite zal zien. JA3Proxy heeft een optie die ons hierbij helpt, genaamd upstream. Door het JA3Proxy-bevel als volgt te starten, ./ja3proxy -addr 127.0.0.1 -client Chrome -version 131 -cert cert.pem -key key.pem -upstream socks5h://USER:PASS@PROVIDER:PORT -debug We kunnen onze verzoeken tunnelen met behulp van onze voorkeur proxy provider. Houd er rekening mee dat u verbinding moet maken via SOCKS5, dus zorg ervoor dat uw provider deze functie ondersteunt. Door de IP te controleren na dit te doen, kan ik zien dat mijn residentiële roterende IP's op hun plaats zijn en ik kan blijven downloaden MRPorter pagina's zonder probleem. 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 Conclusies In dit bericht hebben we gezien hoe u de Akamai Bot Manager op de MrPorter-website kunt omzeilen.Het beschermingsniveau van de website is gemiddeld, dus er is geen complexe browser-fingerprint-uitdaging om te omzeilen, maar in mijn ervaring is het de meest voorkomende gebruikssituatie bij het tegenkomen van Akamai op onze weg. Ik kies ervoor om de JA3Proxy-benadering te volgen om het te omzeilen, zodat deze oplossing kan worden gebruikt in verschillende frameworks.Als u Scrapy gebruikt, kunt u altijd op Scrapy Impersonate vertrouwen, ondanks de beperkingen, of u kunt proberen de cifers handmatig in de juiste volgorde in te stellen. Het artikel maakt deel uit van de “The Lab” serie door Pierluigi Vinciguerra. Bekijk zijn Substack pagina voor meer kennis over Web Scraping. Het artikel maakt deel uit van Serie van Check uit zijn pagina voor meer kennis over Web Scraping. ‘Het laboratorium’ Van Pierluigi Vinciguerra Substantie ‘Het laboratorium’