← Alle Beiträge

Blick ins Browser-Profil: Was `unblocker: true` wirklich tut

Ein Flag betätigt drei Schalter: echte Browser-Header, eine passende Connection-Signatur und Auto-Dekompression für gzip und brotli. Hier ist, was es macht und warum.

Die meisten Scraper scheitern, bevor ein einziger Header gelesen wird.

Der Server prüft die Signatur auf Verbindungsebene, die dein Client übermittelt, und entscheidet, ob du ein Browser bist oder eine Client-Bibliothek, die sich als solcher ausgibt. Python requests, Go net/http, reines cURL: Sie alle liefern beim Handshake einen eindeutigen Fingerprint. Relevante Seiten (DataDome, Akamai, Imperva, die verwaltete Seite von Cloudflare) trennen die Verbindung oder zeigen eine Challenge-Seite, bevor dein User-Agent überhaupt eine Rolle spielt.

Genau das löst unblocker: true auf FourA. Im letzten Monat haben wir die Details finalisiert, damit es absolut zuverlässig läuft.

Was ist neu

unblocker: true ist ein einzelnes Flag bei jedem /api/single-Aufruf. Wenn du es aktivierst, passieren drei Dinge: Wir injizieren das Browser-Header-Set, leiten den Request über einen Transport weiter, der exakt dem Verhalten eines echten Browsers entspricht, und dekomprimieren die Server-Response (gzip, brotli, deflate). Die ersten beiden Funktionen gab es bereits in der Beta. Die dritte (automatische Brotli-Dekomprimierung) wurde am 25. März veröffentlicht, und das Versions-Pinning folgte am nächsten Tag, um Header und Transport synchron zu halten.

Funktionsweise

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-Injection. Wir setzen das vollständige 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 Erkennungsbibliotheken prüfen genau das.

Connection Signature. Unser Transport entspricht auf Byte-Ebene dem Muster einer aktuellen Browser-Session: dieselbe Extension-Reihenfolge, dieselben Cipher-Präferenzen, dieselben Handshake-Besonderheiten. Standard-cURL, Python requests und Go net/http erzeugen Signaturen, die auf geschützter Infrastruktur innerhalb von Millisekunden maschinell markiert werden.

Auto-Dekompression. Wenn unblocker aktiv ist, setzen wir Accept-Encoding auf gzip, deflate, br und der Transport entpackt den Body. Du erhältst einen dekodierten String zurück (oder einen Buffer, wenn du returnBuffer: true übergibst). Kein manuelles Brotli-Handling, keine Diskrepanzen zwischen Headern und Body, wenn eine Seite Deflate statt Gzip wählt.

Warum Version Pinning wichtig ist

Connection Signatures sind an feste Versionen gebunden. Die Wire-Level-Details eines Browsers in diesem Monat unterscheiden sich von denen des Vormonats, und Seiten mit präzisem Fingerprinting bemerken diese Abweichung. Wir pinnen die variablen Teile zusammen, sodass Header, Navigator-Objekte und Connection Signature dieselbe Browser-Version melden.

Das klingt aufwendig, und das ist es auch. Wir wurden bei der Monorepo-Migration im März von einer solchen Diskrepanz getroffen, als sich eine Komponente automatisch aktualisierte und der Rest asynchron wurde. Der Fix bestand aus zwei Commits: die variable Komponente pinnen und sich beim Abgleich nie auf den Package Manager verlassen.

Auswirkungen

In internen Tests gegen Seiten, die prüfen, wer anfragt (Finanzen, Reisen, größere E-Commerce-Plattformen), ist der Unterschied zwischen unblocker: false und unblocker: true der Unterschied zwischen einer Challenge-Page und einem 200er-Status. Ein einfacher HTTP-Client erhält oft direkt beim ersten Versuch einen 403. Dieselbe URL mit unblocker: true liefert die Seite aus, weil der Request exakt wie der beschriebene Browser aussieht.

Für Seiten ohne Fingerprinting (die meisten öffentlichen APIs, ältere CMS-Templates, reine IP-Rate-Limits) ist es völlig in Ordnung, unblocker deaktiviert zu lassen. Das spart einige Millisekunden bei der Negotiation. Setze es dort ein, wo du es brauchst.

Für Power-User

Einige nützliche Patterns.

Kombiniere unblocker mit einem Residential Proxy, wenn das Ziel auch die IP-Reputation prüft. Rechenzentrums-IPs führen trotz perfekter Connection Signature zu Flags, wenn die Seite das ASN auf einer Blocklist führt. Unser Proxy-Endpoint (/api/proxy) rotiert nach Target-Domain, daher reicht es meist aus, "proxy": "residential" zum Request hinzuzufügen.

Überspringe unblocker bei Aufrufen von JSON-APIs, die keine Browser erwarten. Die zusätzlichen Header können bei einer API, die programmatische Clients erwartet (etwa ein Backend beim Aufruf des eigenen Microservices), sogar verdächtig wirken.

Wenn die Website Besucher per JavaScript prüft, bevor sie die Seite anzeigt, reicht unblocker allein nicht aus. Du benötigst den Browser-Endpoint, der das JavaScript der Seite in einem vollständigen Browser ausführt. Das ist ein anderes Produkt mit abweichenden Credit-Preisen, und wir haben die Details in Browser-Tasks: So scrapst du JavaScript-lastige Websites zusammengefasst.

Du kannst unblocker mit dem validate-Block kombinieren, um Responses abzulehnen, die technisch 200 zurückgeben, aber eine Challenge-Seite enthalten:

{
  "url": "https://example.com/products",
  "method": "GET",
  "unblocker": true,
  "validate": {
    "data": { "fail": ["captcha", "Access Denied"] }
  }
}

Das verwandelt lautlose Fehler in klassifizierte Fehler, was für dein Tracking der Erfolgsrate im dashboard wichtig ist.

Wie es weitergeht

Browser veröffentlichen alle vier Wochen eine neue stabile Version. Wir aktualisieren unseren Stack entsprechend. Du musst auf deiner Seite nichts anpassen: unblocker: true verweist immer auf die Browser-Version, die wir End-to-End verifiziert haben.

Die schwierigere Arbeit liegt noch vor uns. HTTP/3-Prüfungen tauchen bereits auf größeren Websites auf, der QUIC-Transport ist kniffliger nachzubilden als der ältere Transport, und die Migration von statischen Header-Bundles hin zu echter dynamischer Emulation beginnt. Geschützte Websites prüfen mittlerweile die Reihenfolge der HTTP/2-Frames, und die Lücke zwischen einer „Library, die wie ein Browser aussieht“ und einem „echten Browser“ wird von beiden Seiten kleiner. Wir berichten darüber, sobald wir es ausliefern.