Die meisten Scraping-Projekte entdecken auf die harte Tour, was eine Website schützt: Am Montag funktioniert der Prototyp, am Dienstag erscheint eine Challenge-Seite, und am Freitag baut das Team alles um einen Headless-Browser herum um. Vieles davon ließe sich bereits am ersten Tag wissen. Bot-Management-Produkte hinterlassen sichtbare Spuren in den Response-Headern und Cookies einer Website, und eine einzige gewöhnliche Anfrage genügt, um sie auszulesen.
Wir haben ein kurzes Lookup-Tool gebaut, das genau das tut, es gegen die Startseiten der Top-1.000-Domains laufen lassen und aufgezeichnet, was ein einfacher HTTP-Client ausgeliefert bekam. Dieser Leitfaden teilt die Ergebnisse, den Code und zeigt, wie man die Antwort bei der Projektplanung nutzt.
Die wichtigsten Erkenntnisse
- Eine einzige Anfrage verrät viel. Vendor-Cookies und Header identifizierten bei 37% der 653 ladbaren Top-Site-Startseiten einen Bot-Protection- oder Edge-Security-Anbieter, und bei 16% ein aktiv laufendes Bot-Management-Produkt.
- Cloudflare war mit Abstand am häufigsten, auf einem Viertel der Startseiten, gefolgt von Akamai. DataDome, AWS WAF, Imperva und HUMAN traten deutlich seltener auf, und DataDome sowie HUMAN forderten oder blockierten jede einzelne Anfrage, die wir an sie sandten.
- Ein einfacher HTTP-Client, der sich als Chrome ausgab, bekam 81% der Startseiten ausgeliefert, wurde bei 10% herausgefordert und bei 9% blockiert. Mit dem Standard-User-Agent der Bibliothek stiegen die Blockierungen auf 16%.
- Sich als Browser auszugeben kann nach hinten losgehen. Die zehn Länder-Storefronts eines großen Händlers lieferten der ehrlichen User-Agent-Angabe der Bibliothek vollständige Startseiten aus, der Anfrage, die sich als Chrome ausgab, dagegen eine ein bis zwei Kilobyte große Challenge-Seite.
- Behandeln Sie das Lookup als Planungsgrundlage: Es zeigt, was zu erwarten ist, ob eine offizielle API oder eine Genehmigung der bessere Weg ist, und wie das Projekt budgetiert werden sollte.
Was eine einzelne Anfrage verraten kann
Bot-Management- und Edge-Security-Produkte funktionieren, indem sie sich vor eine Website schalten und jede Anfrage prüfen. Dazu setzen die meisten von ihnen Cookies im Browser des Besuchers oder fügen Response-Header hinzu, und diese Namen sind stabil und oft dokumentiert:
| Anbieter | Typischer Nachweis | Woher er stammt |
|---|---|---|
| Cloudflare | cf-ray-Header bei allem, was ausgeliefert wird; __cf_bm-Cookie, wenn Bot Management oder Bot Fight Mode aktiv ist; cf-mitigated: challenge auf einer Challenge-Seite | Cloudflare-Dokumentation |
| Akamai | Akamai-GRN-Header mit Anfragenummer; _abck, ak_bmsc, bm_sz-Cookies von Bot Manager | Akamai-Dokumentation für den Header; Cookie-Richtlinien der Website für die Cookies |
| DataDome | datadome-Cookie; x-datadome-Header | DataDome-Dokumentation |
| HUMAN | _px3, _pxhd, _pxvid-Cookies | HUMAN-Dokumentation |
| Imperva | visid_incap_, incap_ses_, nlbi_-Cookies | Cookie-Richtlinien der Website |
| AWS WAF | x-amzn-waf-action: challenge mit HTTP 202 bei einer Challenge; aws-waf-token-Cookie | AWS-Dokumentation |
Beim Lesen der Ergebnisse sind zwei Unterscheidungen wichtig. Hinter einem Content-Delivery-Network zu stehen ist nicht dasselbe wie Bot Management zu betreiben: Ein cf-ray-Header bedeutet, dass die Website Cloudflare nutzt, während ein __cf_bm-Cookie bedeutet, dass ein Cloudflare-Bot-Produkt aktiv Besucher bewertet. Und eine fehlende Signatur beweist nichts; viele Websites betreiben eine eigene Erkennung oder ein Produkt, das bei der ersten Antwort keine Spuren hinterlässt.
Der Code
Das folgende Modul liest eine Response und gibt die erkannten Anbieter mit Nachweis zurück, ob ein Bot-Management-Produkt aktiv ist, und was die Anfrage erhalten hat: ausgeliefert, herausgefordert oder blockiert.
import re
# Cookies that each vendor's bot or WAF product sets, and headers it adds. Cookies are the strongest evidence.
SIGNATURES = {
"Cloudflare": {"headers": ["cf-ray"], "cookies": [r"^__cf_bm$", r"^cf_clearance$"]},
"Akamai": {"headers": ["akamai-grn"], "cookies": [r"^_abck$", r"^ak_bmsc$", r"^bm_sz$", r"^bm_sv$"]},
"DataDome": {"headers": ["x-datadome"], "cookies": [r"^datadome$"]},
"HUMAN": {"headers": [], "cookies": [r"^_px(3|hd|vid|cvid|de)$"]},
"Imperva": {"headers": [], "cookies": [r"^visid_incap_\d+$", r"^incap_ses_", r"^nlbi_\d+$", r"^reese84$"]},
"AWS WAF": {"headers": ["x-amzn-waf-action"], "cookies": [r"^aws-waf-token$"]},
}
# Evidence of an active bot-management product, as opposed to only the CDN in front of the site.
BOT_PRODUCT_COOKIES = [r"^__cf_bm$", r"^cf_clearance$", r"^_abck$", r"^ak_bmsc$", r"^bm_sz$", r"^datadome$", r"^_px", r"^reese84$"]
def cookie_names(response):
"""Names of every cookie the response tried to set."""
return {c.split("=", 1)[0].strip() for c in response.raw.headers.getlist("Set-Cookie")}
def detect_stack(response):
"""Return {vendor: [evidence]} from one response's headers and cookies."""
headers = {k.lower() for k in response.headers}
cookies = cookie_names(response)
found = {}
for vendor, sig in SIGNATURES.items():
evidence = [f"header {h}" for h in sig["headers"] if h in headers]
evidence += [f"cookie {c}" for c in sorted(cookies) if any(re.match(p, c) for p in sig["cookies"])]
if evidence:
found[vendor] = evidence
server = response.headers.get("server", "").lower()
if server == "cloudflare":
found.setdefault("Cloudflare", []).append("server header")
if "akamaighost" in server:
found.setdefault("Akamai", []).append("server header")
return found
def bot_product_active(response):
"""True when a cookie shows a bot-management product, not just a CDN, handled the request."""
return any(re.match(p, c) for c in cookie_names(response) for p in BOT_PRODUCT_COOKIES)
def outcome(response):
"""Classify what a request got: served, challenged or blocked."""
body = response.text[:20000].lower()
if (response.headers.get("cf-mitigated", "").lower() == "challenge"
or response.headers.get("x-amzn-waf-action", "").lower() == "challenge"
or "captcha-delivery.com" in body):
return "challenged"
if response.status_code in (401, 403, 405, 429) or response.status_code >= 500 or "incapsula incident id" in body:
return "blocked"
return "served"
Es funktioniert mit einer Response der requests-Bibliothek und liest Cookies aus den rohen Set-Cookie-Headern, sodass es Cookies sieht, die der Client sonst nicht behalten würde. Zu beachten ist, was „ausgeliefert” hier bedeutet: Es wurde kein Challenge- oder Block-Signal gefunden. Es beweist nicht, dass die Seite den echten Inhalt enthielt, eine Lücke, auf die wir weiter unten zurückkommen.
Was wir bei den Top-1.000-Domains gefunden haben
Am 3. Oktober 2026 haben wir die Startseite jeder der Top-1.000-Domains im Tranco-Ranking angefragt, einmal mit einem Chrome-User-Agent-String und einmal mit dem Standard der requests-Bibliothek, von einer einzelnen Verbindung in Rumänien aus. Beide Anfragen kamen vom selben Python-HTTP-Client, der kein JavaScript ausführt und nicht den Netzwerk-Fingerabdruck eines Browsers hat. 653 unterschiedliche Websites lieferten eine HTML-Startseite zurück; der Rest waren Content-Netzwerke, API-Hosts und andere Domains ohne eine solche.
| Erkannter Anbieter | Startseiten | Mit aktivem Bot-Management-Cookie |
|---|---|---|
| Cloudflare | 162 (24,8%) | 79 |
| Akamai | 55 (8,4%) | 16 |
| AWS WAF | 14 (2,1%) | 0 |
| DataDome | 8 (1,2%) | 8 |
| HUMAN | 2 | 2 |
| Imperva | 2 | 0 |
| Einer der oben genannten | 241 (36,9%) | 105 (16,1%) |
| Keiner erkannt | 412 (63,1%) | 0 |
Nur zwei Startseiten zeigten zwei Anbieter gleichzeitig. Zehn der 14 AWS-WAF-Websites waren Länder-Storefronts desselben Händlers.
Was die Anfragen erhalten haben:
| Anfrage | Ausgeliefert | Herausgefordert | Blockiert |
|---|---|---|---|
| Chrome-User-Agent, 653 Startseiten | 530 (81,2%) | 64 (9,8%) | 59 (9,0%) |
| Standard-User-Agent der Bibliothek, 650 Startseiten | 500 (76,9%) | 49 (7,5%) | 101 (15,5%) |
Und aufgeschlüsselt nach dem Schutz der Website, wobei nur Websites gezählt werden, bei denen beide Anfragen abgeschlossen wurden:
| Erkannter Schutz | Websites | Chrome-User-Agent: herausgefordert oder blockiert | Bibliotheksstandard: herausgefordert oder blockiert |
|---|---|---|---|
| Cloudflare | 162 | 54 | 63 |
| Akamai | 54 | 26 | 22 |
| DataDome | 7 | 7 | 7 |
| Keiner erkannt | 411 | 19 | 53 |
Was die Ergebnisse aussagen
Der Großteil des Top-Webs beantwortet eine einfache Anfrage. Vier von fünf Startseiten lieferten einem einfachen HTTP-Client, der sich als Chrome ausgab, ohne sichtbare Challenge aus. Eine Startseite ist jedoch die einfachste Seite einer Website; Suchergebnisse, Preise und Checkout-Abläufe sind in der Regel strenger geschützt als die Eingangstür.
Einfache Filter und ernsthafte Produkte verhalten sich unterschiedlich. Bei Websites ohne erkennbaren Anbieter wurde der Standard-User-Agent der Bibliothek fast dreimal so oft herausgefordert oder blockiert wie der Chrome-String, 53 Mal gegenüber 19 Mal. Das ist das typische Signaturmuster für einfache User-Agent-Filterung. Bei Websites mit DataDome wurden beide Anfragen jedes Mal herausgefordert oder blockiert; der User-Agent machte keinen Unterschied.
Eine falsch zugeordnete Identität kann schlimmer sein als eine ehrliche. Die zehn Länder-Storefronts des Händlers beantworteten die Anfrage, die sich als Chrome ausgab, mit einer ein bis zwei Kilobyte großen Challenge- oder Platzhalterseite, und den ehrlichen User-Agent der Bibliothek mit der vollständigen Startseite, zwischen 678 KB und 1,4 MB. Wir haben die Prüfung für alle zehn wiederholt, und das Muster blieb bestehen. Ein Chrome-User-Agent-String, der über eine Verbindung ankommt, die nicht wie Chrome aussieht, wie in TLS- und HTTP/2-Fingerprinting erläutert, ist selbst ein Signal.
Ein erfolgreicher Status ist keine erfolgreiche Seite. Drei dieser Platzhalterseiten kamen mit HTTP 200 und ohne Challenge-Header zurück, sodass eine reine Statusprüfung sie als ausgeliefert zählt. Validieren Sie Inhalte, nicht nur Statuscodes, wie in der stillen Fehlerquote und wie man erkennt, wann eine Website gefälschte oder blockierte Inhalte ausliefert beschrieben.
Das Lookup zur Projektplanung nutzen
Führen Sie das Lookup auf den Seiten aus, die Sie tatsächlich benötigen, nicht nur auf der Startseite, und lassen Sie die Antwort den Plan bestimmen:
| Was das Lookup zeigt | Was es in der Regel bedeutet | Sinnvoller nächster Schritt |
|---|---|---|
| Kein Anbieter, Anfrage ausgeliefert | Wenig oder kein Bot Management auf dieser Seite | Einfaches HTTP mit ehrlicher Identifikation, moderatem Tempo und den richtigen Headern |
| Nur CDN, kein Bot-Cookie | Edge-Security ohne aktive Bot-Bewertung | Einfaches HTTP, aber auf Challenges achten, wenn das Volumen steigt |
| Bot-Management-Cookie, Anfrage ausgeliefert | Aktive Bewertung, die diese Anfrage zugelassen hat | Challenges bei steigendem Umfang erwarten; Überwachung mit einem Target-Health-Score |
| Beim ersten Request herausgefordert | Eine bewusste Entscheidung, automatisierte Clients zu filtern | Zunächst nach einer offiziellen API oder einem Datenfeed suchen, dann abwägen, ob ein Browser gerechtfertigt ist, gemäß wann man einen Headless-Browser braucht |
| Beim ersten Request blockiert | Strenge Regeln, oft nach Netzwerk oder Region | Prüfen, ob die Daten anderweitig verfügbar sind, einschließlich der API hinter der Seite, und ob die Blockierung regional ist |
Das Lookup sagt auch etwas über die Absicht aus. Eine Website, die ein aktives Bot-Management-Produkt betreibt, hat sich entschieden, automatisierten Zugriff zu kontrollieren, und das sollte neben ihren Nutzungsbedingungen und ihrer robots.txt abgewogen werden, wie in robots.txt, AI-Opt-outs und Reservierungssignale erläutert. Für viele Projekte ist die richtige Antwort auf ein stark geschütztes Ziel eine Lizenz, eine Partnerschaft oder eine offizielle API statt einer Eskalation. Wo das Sammeln angemessen ist, erklärt die Eskalationsleiter für geschützte Websites die Optionen nach Kosten geordnet.
Grenzen der Messung
- Nur Startseiten. Tiefere Seiten sind oft anders geschützt.
- Jeweils eine Anfrage, von einem Netzwerk. Ergebnisse können je nach Land, Netzwerk-Reputation, Tageszeit und Anfragehistorie variieren; wir haben regionale Unterschiede in welche Länder am häufigsten geoblockt werden behandelt.
- Kein Browser. Viele Challenges sind darauf ausgelegt, von einem echten Browser mit laufendem JavaScript bestanden zu werden; unser Client konnte das per Design nicht.
- Signaturen übersehen Dinge. Hausinterne Erkennung und Produkte, die bei der ersten Anfrage keine Spur hinterlassen, werden als „keiner erkannt” gezählt, sodass der tatsächliche Anteil geschützter Websites höher liegt.
Fazit
Eine einzige gewöhnliche Anfrage verrät das meiste, was man für die Planung eines Scraping-Projekts braucht: wer die Website schützt, ob Bot-Scoring aktiv ist und wie ein einfacher Client behandelt wird. Bei den Top-1.000-Domains antwortete der Großteil der Startseiten, ein Viertel saß hinter Cloudflare, eine von sechs betrieb ein aktives Bot-Management-Produkt, und die strengsten Produkte forderten oder blockierten jede Anfrage, die wir sandten.
Führen Sie das Lookup aus, bevor Sie den Scraper schreiben, auf den Seiten, die Sie brauchen. Lassen Sie es Ihnen sagen, wann Sie es einfach halten sollten, wann Sie einen Browser einplanen müssen und wann Sie stattdessen nach einem offiziellen Weg zu den Daten suchen sollten.
Quellen und Referenzen
- Cloudflare, Cloudflare cookies und detecting a challenge page response.
- Akamai, Global request number.
- DataDome, Cookies and stored data.
- HUMAN, Use of cookies and web storage.
- AWS, CAPTCHA and Challenge in AWS WAF.
- Tranco, list Q2K34.
- Von Shifter angefragte Startseiten am 3. Oktober 2026, unter Verwendung des obigen Codes.