Alle Beiträge

Einblicke in das Unblocker-Flag: Was `unblocker: true` wirklich macht

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 Connection-Signatur, die dein Client sendet, und entscheidet, ob du ein Browser bist oder eine Client-Library, die sich als einer ausgibt. Python requests, net/http von Go, reines curl: alle übergeben im Moment der Begrüßung einen unverwechselbaren Fingerprint. Seiten, die darauf achten (Datadome, Akamai, Imperva, die verwaltete Seite von Cloudflare), verwerfen die Verbindung oder zeigen dir eine Challenge-Seite, bevor dein User-Agent-String überhaupt eine Rolle spielt.

Genau das löst unblocker: true bei FourA. Im letzten Monat haben wir die Komponenten fixiert, die es zuverlässig machen.

Was neu ist

unblocker: true ist ein einzelnes Flag bei jedem /api/single call. Aktiviere es und wir machen drei Dinge: das Browser-Header-Set injizieren, den request über einen Transport senden, der dem entspricht, was ein echter Browser übermittelt, und alles dekomprimieren, was der Server zurückgibt (gzip, brotli, deflate). Die ersten beiden sind seit der Beta verfügbar. Die dritte (brotli Auto-Dekompression) wurde am 25. März ausgeliefert, und das Version-Pinning folgte am nächsten Tag, um Header und Transport synchron 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-Injection. 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 ist wichtig. Echte Browser senden diese in einer bestimmten Sequenz, und Detection-Libraries prüfen das.

Connection-Signatur. Unser Transport entspricht auf Byte-Ebene einer aktuellen Browser-Sitzung: die gleiche Reihenfolge der Extensions, die gleichen Cipher-Präferenzen, die gleichen Handshake-Eigenheiten. Standard-curl, Python requests und net/http von Go erzeugen Signaturen, die auf geschützter Infrastruktur innerhalb von Millisekunden maschinell markiert werden.

Auto-Dekompression. Wenn unblocker aktiviert ist, setzen wir Accept-Encoding auf gzip, deflate, br und der Transport entpackt den Body. Du bekommst einen dekodierten String zurück (oder einen Buffer, wenn du returnBuffer: true übergibst). Kein manuelles Handling von brotli, keine Header-gegen-Body-Abweichungen, wenn eine Seite deflate statt gzip wählt.

Warum Version-Pinning wichtig ist

Connection-Signaturen sind an Versionen gebunden. Die Details eines Browsers auf Netzwerkebene sind in diesem Monat nicht dieselben wie im letzten, und eine Seite, die sorgfältiges Fingerprinting betreibt, bemerkt diese Abweichung. Wir pinnen die beweglichen Teile zusammen, sodass Header, Navigator-Objekte und die Connection-Signatur alle dieselbe Browser-Version melden.

Wenn das fummelig klingt, dann ist es das auch. Wir wurden während der Monorepo-Migration im März von einer Diskrepanz erwischt, als sich ein Teil automatisch aktualisierte und der Rest asynchron wurde. Der Fix bestand aus zwei Commits: das bewegliche Teil pinnen und niemals dem Package-Manager vertrauen, dass er die Dinge für dich synchron hält.

Auswirkungen

In internen Tests gegen stark gefingerprintete Ziele (Finanzen, Reisen, geschützter E-Commerce) ist der Unterschied zwischen unblocker: false und unblocker: true der Unterschied zwischen einer Challenge-Seite und einer 200. Reines curl, das auf verwaltetes Cloudflare trifft, landet beim ersten Versuch auf einem 403. Dieselbe URL mit unblocker: true kommt durch, weil die Verbindung auf Netzwerkebene wie eine Browser-Sitzung aussieht.

Aber bei Seiten ohne Fingerprinting (die meisten öffentlichen APIs, ältere CMS-Templates, alles, was nur durch IP rate limits geschützt ist) ist es in Ordnung, unblocker wegzulassen. Das spart einige Millisekunden bei der Verhandlung. Nutze es dort, wo du es brauchst.

Für Power-User

Ein paar Muster, die man kennen sollte.

Kombiniere unblocker mit einem Residential Proxy, wenn das Ziel auch die IP-Reputation prüft. Datacenter-IPs plus eine perfekte Connection-Signatur schlagen trotzdem bei ASNs an, die die Seite auf einer Blacklist hat. Unser proxy endpoint (/api/proxy) rotiert nach Zieldomain, daher reicht es meist aus, "proxy": "residential" zum request hinzuzufügen.

Lass unblocker weg, wenn du JSON APIs aufrufst, die sich nicht um Browser kümmern. Die zusätzlichen Header können für eine API, die einen programmatischen Client erwartet (etwa ein Backend, das seinen eigenen Microservice aufruft), verdächtig wirken.

Wenn die Seite JavaScript-Anti-Bot ausführt (interaktive Challenges von Turnstile, PerimeterX auf der strengsten Stufe, Akamai Bot Manager mit aufgedrehter Heuristik), reicht unblocker allein nicht aus. Du benötigst den Browser-Endpoint, der die Challenge in einem vollständigen Browser ausführt. Das ist ein anderes Produkt mit anderer Credit-Preisgestaltung, und wir haben darüber in Browser Tasks: How to Scrape JavaScript-Heavy Sites geschrieben.

Und du kannst unblocker mit dem validate Block kombinieren, um Responses abzulehnen, die technisch eine 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 stille Fehler in klassifizierte Fehler, was für dein Erfolgsquoten-Tracking im dashboard wichtig ist.

Was als Nächstes kommt

Browser veröffentlichen alle vier Wochen eine neue Stable-Version. Wir passen unseren Stack entsprechend an. Du musst auf deiner Seite nichts anfassen: unblocker: true zeigt weiterhin auf die Browser-Version, die wir Ende-zu-Ende verifiziert haben.

Die schwerere Arbeit liegt noch vor uns. HTTP/3-Fingerprinting taucht bereits bei verwaltetem Anti-Bot auf, QUIC-Transport ist kniffliger nachzubilden als ältere Transporte, und die Migration weg von statischen Header-Bundles hin zu wirklich dynamischer Emulation beginnt. Geschützte Seiten sind dazu übergegangen, die Reihenfolge der HTTP/2-Frames zu prüfen, und die Lücke zwischen "Library, die wie ein Browser aussieht" und "ein Browser" wird von beiden Enden schrumpfen. Wir werden darüber schreiben, wenn wir es veröffentlichen.