Die meisten Scraper scheitern, bevor ein einziger Header gelesen wird.
Der Server analysiert den TLS-Handshake (Reihenfolge der Cipher Suites, Anordnung der Extensions, Kurven-Präferenzen) und entscheidet, ob du ein Browser bist oder eine Client-Bibliothek, die sich als solcher ausgibt. Python-Requests, net/http von Go, reines curl: Sie alle übergeben einen markanten Fingerprint, sobald sie Hallo sagen. Websites, die darauf achten (Datadome, Akamai, Imperva, die verwaltete Seite von Cloudflare), trennen die Verbindung oder zeigen dir eine Challenge-Seite an, noch bevor dein User-Agent-String überhaupt eine Rolle spielt.
Genau das löst unblocker: true auf FourA. Im letzten Monat haben wir die Teile festgeschrieben, die für eine zuverlässige Funktion sorgen.
Was neu ist
unblocker: true ist ein einzelnes Flag bei jedem /api/single-Aufruf. Schalte es ein und wir tun drei Dinge: das Browser-Header-Set injizieren, den Request über curl-impersonate mit einem echten Browser-TLS-Fingerprint senden und alles dekomprimieren, was der Server zurückgibt (gzip, brotli, deflate). Die ersten beiden Funktionen waren seit der Beta verfügbar. Die dritte (automatische Brotli-Dekomprimierung) wurde am 25. März veröffentlicht, und die Pinning-Arbeiten für die Browser-Version folgten am nächsten Tag, um Header und TLS im Gleichschritt zu halten.
Wie es funktioniert
So sieht ein Request aus:
curl -X POST "https://api.foura.ai/api/single" \
-H "Content-Type: application/json" \
-H "x-api-key: YOUR_API_KEY" \
-d '{
"url": "https://example.com/products",
"method": "GET",
"unblocker": true
}'
Darunter laufen drei Schichten.
Header-Injektion. Wir setzen das komplette Browser-Header-Bundle: User-Agent, Sec-Ch-Ua, Sec-Ch-Ua-Platform, Sec-Fetch-Site, Sec-Fetch-Mode, Sec-Fetch-Dest, Accept, Accept-Language und Accept-Encoding. Die Reihenfolge zählt. Echte Browser senden diese in einer bestimmten Sequenz, und Erkennungs-Bibliotheken prüfen genau das.
TLS-Fingerprint. curl-impersonate 0.8.2 kompiliert libcurl gegen BoringSSL und ordnet TLS-Extensions so an, dass sie dem entsprechen, was die Ziel-Browserversion tatsächlich über die Leitung sendet. Deine JA3- und JA4-Hashes sind identisch mit einer echten Browser-Session. Standard-curl, Python-Requests und net/http von Go erzeugen Fingerprints, die auf geschützter Infrastruktur innerhalb von Millisekunden automatisch markiert werden.
Automatische Dekomprimierung. Wenn unblocker aktiv ist, setzen wir Accept-Encoding auf gzip, deflate, br und lassen libcurl den Body entpacken. Du erhältst einen decodierten String zurück (oder einen Buffer, wenn du returnBuffer: true übergibst). Keine manuelle Brotli-Verarbeitung, keine Diskrepanzen zwischen Headern und Body, wenn eine Website deflate statt gzip wählt.
Warum Version-Pinning wichtig ist
TLS-Fingerprints sind an Versionen gebunden. Die Cipher-Reihenfolge eines Browsers in diesem Monat ist nicht dieselbe wie im letzten, und eine Website, die Fingerprinting sorgfältig einsetzt, bemerkt diese Abweichung. curl-impersonate liefert Profile für bestimmte Browser-Builds, und wir pinnen unsere echte Browser-Binary auf den Build, den curl-impersonate aktuell anvisiert. Header, Navigator-Objekte und TLS melden alle dieselbe Version.
Wenn das kompliziert klingt, dann weil es das ist. Wir wurden während der Monorepo-Migration im März von einer Diskrepanz kalt erwischt, als sich der Browser automatisch aktualisierte und die Header nicht mehr mit curl-impersonate synchron waren. Der Fix bestand aus zwei Commits: die Browser-Binary pinnen und niemals dem Paketmanager vertrauen, dass er sie für dich synchron hält.
Auswirkungen
In internen Tests gegen stark per Fingerprinting geschützte Ziele (Finanzen, Reisen, geschützter E-Commerce) ist der Unterschied zwischen unblocker: false und unblocker: true der Unterschied zwischen einer Challenge-Seite und einem 200er-Statuscode. Reines curl, das auf ein verwaltetes Cloudflare trifft, landet direkt beim ersten Versuch auf einem 403. Dieselbe URL mit unblocker: true kommt durch, weil das TLS-Hello wie ein echter Browser-Handshake aussieht.
Aber für Websites, die kein Fingerprinting nutzen (die meisten öffentlichen APIs, ältere CMS-Templates, alles, was nur durch IP-Rate-Limits geschützt ist), ist es völlig in Ordnung, unblocker deaktiviert zu lassen, was ein paar Millisekunden bei der TLS-Aushandlung spart. Nutze es dort, wo du es brauchst.
Für Power-User
Ein paar nützliche Patterns.
Kombiniere unblocker mit einem Residential-Proxy, wenn das Ziel auch die IP-Reputation prüft. Rechenzentrum-IPs führen trotz eines perfekten TLS-Handshakes immer noch zu Flags bei ASNs, die die Website auf der Blacklist hat. Unser Proxy-Endpoint (/api/proxy) rotiert nach Ziel-Domain, daher reicht es meist aus, "proxy": "residential" zum Request hinzuzufügen.
Verzichte auf unblocker, wenn du JSON-APIs aufrufst, denen Browser egal sind. Die zusätzlichen Header können für eine API, die einen programmatischen Client erwartet (zum Beispiel ein Backend, das seinen eigenen Microservice aufruft), sogar verdächtig wirken.
Wenn die Website JavaScript-Anti-Bot-Maßnahmen nutzt (interaktive Turnstile-Challenges, Perimeter X in der strengsten Konfiguration, Akamai Bot Manager mit hochgedrehten Heuristiken), reicht unblocker allein nicht aus. Du benötigst den Browser-Endpoint, der echtes Chromium ausführt und die Challenge lösen kann. Das ist ein anderes Produkt mit anderer Credit-Abrechnung, das wir in Browser-Tasks: Wie man JavaScript-lastige Websites scrapt beschrieben haben.
Und du kannst unblocker mit dem validate-Block kombinieren, um Responses abzuweisen, die technisch zwar einen 200er-Statuscode zurückgeben, aber eine Challenge-Seite enthalten:
{
"url": "https://example.com/products",
"method": "GET",
"unblocker": true,
"validate": {
"data": { "fail": ["captcha", "Access Denied"] }
}
}
Das verwandelt unbemerkte Fehler in klassifizierte Fehler, was für dein Erfolgsraten-Tracking im Dashboard wichtig ist.
Was als Nächstes ansteht
Browser veröffentlichen alle vier Wochen eine neue stabile Version. Der Maintainer von curl-impersonate zieht meist einen Monat später nach, und wir aktualisieren unseren Stack, sobald das geschieht. Du musst auf deiner Seite nichts ändern: unblocker: true zeigt weiterhin auf die Browserversion, die wir End-to-End verifiziert haben.
Die schwierigere Arbeit liegt noch vor uns. HTTP/3-Fingerprinting taucht bereits bei verwalteten Anti-Bot-Systemen auf, der QUIC-Transport ist schwieriger zu fälschen als TLS 1.3, und die Migration weg von statischen Header-Bundles hin zu echter dynamischer Emulation beginnt. Geschützte Websites prüfen mittlerweile die HTTP/2-Frame-Reihenfolge und JA4+-Varianten, und die Lücke zwischen „curl, das wie ein Browser aussieht“ und „einem echten Browser“ wird von beiden Seiten schrumpfen. Wir werden darüber schreiben, sobald wir es veröffentlichen.