La plupart des projets de scraping découvrent à la dure ce qui protège un site : le prototype fonctionne le lundi, une page de challenge apparaît le mardi, et dès le vendredi l’équipe reconstruit tout autour d’un navigateur headless. Une grande partie de cela pourrait être connue dès le premier jour. Les produits de gestion des bots laissent des traces visibles dans les en-têtes de réponse et les cookies d’un site, et une seule requête ordinaire suffit pour les lire.
Nous avons construit un court outil de vérification qui fait exactement cela, l’avons exécuté sur les pages d’accueil des 1000 principaux domaines, et avons enregistré ce qu’un client HTTP ordinaire recevait. Ce guide présente les résultats, le code, et comment utiliser la réponse lors de la planification d’un projet.
Points clés à retenir
- Une seule requête révèle beaucoup. Les cookies et en-têtes des fournisseurs ont identifié un fournisseur de protection contre les bots ou de sécurité en périphérie sur 37% des 653 pages d’accueil de sites majeurs que nous avons pu charger, et un produit de gestion des bots activement en fonction sur 16%.
- Cloudflare était de loin le plus répandu, sur un quart des pages d’accueil, suivi par Akamai. DataDome, AWS WAF, Imperva et HUMAN apparaissaient beaucoup moins souvent, et DataDome et HUMAN ont challengé ou bloqué chaque requête que nous leur avons envoyée.
- Un client HTTP ordinaire se faisant passer pour Chrome a reçu 81% des pages d’accueil, a été challengé sur 10% et bloqué sur 9%. Avec le User-Agent par défaut de la bibliothèque, les blocages sont montés à 16%.
- Se faire passer pour un navigateur peut se retourner contre vous. Les dix vitrines nationales d’un grand détaillant ont servi des pages d’accueil complètes au User-Agent honnête de la bibliothèque et une page de challenge d’un à deux kilo-octets à la requête qui se faisait passer pour Chrome.
- Traitez cet outil de vérification comme une donnée de planification : il vous indique à quoi vous attendre, si une API officielle ou une permission est la meilleure voie, et comment budgétiser le projet.
Ce qu’une seule requête peut révéler
Les produits de gestion des bots et de sécurité en périphérie fonctionnent en se plaçant devant un site web et en inspectant chaque requête. Pour ce faire, la plupart d’entre eux définissent des cookies sur le navigateur du visiteur ou ajoutent des en-têtes de réponse, et ces noms sont stables et souvent documentés :
| Fournisseur | Preuve typique | D’où cela provient |
|---|---|---|
| Cloudflare | En-tête cf-ray sur tout ce qu’il sert ; cookie __cf_bm lorsque Bot Management ou Bot Fight Mode est activé ; cf-mitigated: challenge sur une page de challenge | Documentation de Cloudflare |
| Akamai | En-tête de numéro de requête Akamai-GRN ; cookies _abck, ak_bmsc, bm_sz de Bot Manager | Documentation d’Akamai pour l’en-tête ; politiques de cookies des sites pour les cookies |
| DataDome | Cookie datadome ; en-tête x-datadome | Documentation de DataDome |
| HUMAN | Cookies _px3, _pxhd, _pxvid | Documentation de HUMAN |
| Imperva | Cookies visid_incap_, incap_ses_, nlbi_ | Politiques de cookies des sites |
| AWS WAF | x-amzn-waf-action: challenge avec HTTP 202 sur un challenge ; cookie aws-waf-token | Documentation d’AWS |
Deux distinctions comptent lors de la lecture des résultats. Être derrière un réseau de diffusion de contenu n’est pas la même chose qu’exécuter une gestion des bots : un en-tête cf-ray signifie que le site utilise Cloudflare, tandis qu’un cookie __cf_bm signifie qu’un produit de bot Cloudflare note activement les visiteurs. Et une signature manquante ne prouve rien ; de nombreux sites exécutent leur propre détection ou un produit qui ne laisse aucune trace sur la première réponse.
Le code
Le module ci-dessous lit une réponse et renvoie les fournisseurs qu’il détecte avec les preuves, si un produit de gestion des bots est actif, et ce que la requête a obtenu : servie, challengée ou bloquée.
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"
Il fonctionne sur une réponse de la bibliothèque requests et lit les cookies à partir des en-têtes bruts Set-Cookie, de sorte qu’il voit des cookies que le client ne conserverait pas autrement. Notez ce que signifie « servie » ici : aucun signal de challenge ou de blocage n’a été trouvé. Cela ne prouve pas que la page contenait le contenu réel, un écart sur lequel nous revenons ci-dessous.
Ce que nous avons trouvé sur les 1000 principaux domaines
Le 3 octobre 2026, nous avons requêté la page d’accueil de chacun des 1000 principaux domaines du classement Tranco, une fois avec une chaîne User-Agent Chrome et une fois avec la valeur par défaut de la bibliothèque requests, depuis une seule connexion en Roumanie. Les deux requêtes provenaient du même client HTTP Python, qui n’exécute aucun JavaScript et n’a pas l’empreinte réseau d’un navigateur. 653 sites distincts ont renvoyé une page d’accueil HTML ; le reste étaient des réseaux de contenu, des hôtes d’API et d’autres domaines sans page d’accueil.
| Fournisseur détecté | Pages d’accueil | Avec un cookie de gestion des bots actif |
|---|---|---|
| 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 |
| L’un des ci-dessus | 241 (36,9%) | 105 (16,1%) |
| Aucun détecté | 412 (63,1%) | 0 |
Seulement deux pages d’accueil ont montré deux fournisseurs à la fois. Dix des 14 sites AWS WAF étaient des vitrines nationales du même détaillant.
Ce que les requêtes ont obtenu :
| Requête | Servie | Challengée | Bloquée |
|---|---|---|---|
| User-Agent Chrome, 653 pages d’accueil | 530 (81,2%) | 64 (9,8%) | 59 (9,0%) |
| User-Agent par défaut de la bibliothèque, 650 pages d’accueil | 500 (76,9%) | 49 (7,5%) | 101 (15,5%) |
Et détaillé selon ce qui protégeait le site, en comptant les sites où les deux requêtes ont abouti :
| Protection détectée | Sites | User-Agent Chrome : challengée ou bloquée | Par défaut de la bibliothèque : challengée ou bloquée |
|---|---|---|---|
| Cloudflare | 162 | 54 | 63 |
| Akamai | 54 | 26 | 22 |
| DataDome | 7 | 7 | 7 |
| Aucun détecté | 411 | 19 | 53 |
Ce que disent les résultats
La majeure partie du web de premier plan répond à une requête ordinaire. Quatre pages d’accueil sur cinq ont servi un client HTTP basique se faisant passer pour Chrome sans challenge visible. Une page d’accueil est cependant la page la plus facile d’un site ; les résultats de recherche, les prix et les parcours de paiement sont généralement protégés plus strictement que la porte d’entrée.
Les filtres simples et les produits sérieux se comportent différemment. Sur les sites sans fournisseur détectable, le User-Agent par défaut de la bibliothèque a été challengé ou bloqué près de trois fois plus souvent que la chaîne Chrome, 53 fois contre 19. C’est la signature d’un simple filtrage par User-Agent. Sur les sites exécutant DataDome, les deux requêtes ont été challengées ou bloquées à chaque fois ; le User-Agent n’a fait aucune différence.
Une identité mal assortie peut être pire qu’une identité honnête. Les dix vitrines nationales du détaillant ont répondu à la requête se faisant passer pour Chrome avec une page de challenge ou de remplacement d’un à deux kilo-octets, et au User-Agent honnête de la bibliothèque avec la page d’accueil complète, entre 678 Ko et 1,4 Mo. Nous avons répété la vérification pour les dix et le schéma s’est maintenu. Une chaîne User-Agent Chrome arrivant sur une connexion qui ne ressemble pas à Chrome, comme expliqué dans l’empreinte TLS et HTTP/2, est elle-même un signal.
Un statut réussi n’est pas une page réussie. Trois de ces pages de remplacement sont revenues avec un HTTP 200 et aucun en-tête de challenge, de sorte qu’une vérification basée uniquement sur le statut les compte comme servies. Validez le contenu, pas seulement les codes de statut, comme couvert dans le taux d’échec silencieux et comment savoir quand un site vous sert un contenu faux ou bloqué.
Utiliser l’outil de vérification pour planifier un projet
Exécutez l’outil de vérification sur les pages dont vous avez réellement besoin, pas seulement la page d’accueil, et laissez la réponse façonner le plan :
| Ce que montre l’outil de vérification | Ce que cela signifie généralement | Prochaine étape sensée |
|---|---|---|
| Aucun fournisseur, requête ordinaire servie | Peu ou pas de gestion des bots sur cette page | HTTP ordinaire avec identification honnête, rythme modeste, et les bons en-têtes |
| CDN uniquement, pas de cookie de bot | Sécurité en périphérie sans notation active des bots | HTTP ordinaire, mais surveillez les challenges à mesure que le volume augmente |
| Cookie de gestion des bots, requête servie | Notation active qui a permis cette requête | Attendez-vous à des challenges à grande échelle ; surveillez avec un score de santé de la cible |
| Challengée dès la première requête | Une décision délibérée de filtrer les clients automatisés | Cherchez d’abord une API officielle ou un flux de données, puis considérez si un navigateur est justifié, selon quand vous avez besoin d’un navigateur headless |
| Bloquée dès la première requête | Règles strictes, souvent par réseau ou région | Vérifiez si les données sont disponibles autrement, y compris l’API derrière la page, et si le blocage est régional |
L’outil de vérification en dit également long sur l’intention. Un site qui exécute un produit de gestion des bots actif a décidé de contrôler l’accès automatisé, et cela mérite d’être pesé aux côtés de ses conditions d’utilisation et de son robots.txt, comme discuté dans robots.txt, opt-outs IA et signaux de réservation. Pour de nombreux projets, la bonne réponse face à une cible fortement protégée est une licence, un partenariat ou une API officielle plutôt qu’une escalade. Là où la collecte est appropriée, l’échelle d’escalade pour les sites protégés explique les options par ordre de coût.
Limites de la mesure
- Pages d’accueil uniquement. Les pages plus profondes sont souvent protégées différemment.
- Une seule requête chacune, depuis un seul réseau. Les résultats peuvent différer selon le pays, la réputation du réseau, l’heure de la journée et l’historique des requêtes ; nous avons couvert les différences régionales dans quels pays sont le plus géo-bloqués.
- Aucun navigateur. De nombreux challenges sont conçus pour être réussis par un vrai navigateur exécutant du JavaScript ; notre client ne le pouvait pas, par conception.
- Les signatures manquent des choses. La détection maison et les produits qui ne laissent aucune trace lors de la première requête sont comptés comme « aucun détecté », de sorte que la part réelle de sites protégés est plus élevée.
En résumé
Une seule requête ordinaire vous apprend l’essentiel de ce dont vous avez besoin pour planifier un projet de scraping : qui protège le site, si la notation des bots est active, et comment un client ordinaire est traité. Sur les 1000 principaux domaines, la plupart des pages d’accueil ont répondu, un quart se trouvait derrière Cloudflare, un sur six exécutait un produit de gestion des bots actif, et les produits les plus stricts ont challengé ou bloqué chaque requête que nous avons envoyée.
Exécutez l’outil de vérification avant d’écrire le scraper, sur les pages dont vous avez besoin. Laissez-le vous indiquer quand garder les choses simples, quand planifier pour un navigateur, et quand chercher plutôt une voie officielle vers les données.
Sources et références
- Cloudflare, Cookies Cloudflare et détection de la réponse d’une page de challenge.
- Akamai, Numéro de requête global.
- DataDome, Cookies et données stockées.
- HUMAN, Utilisation des cookies et du stockage web.
- AWS, CAPTCHA et Challenge dans AWS WAF.
- Tranco, liste Q2K34.
- Pages d’accueil requêtées par Shifter le 3 octobre 2026, à l’aide du code ci-dessus.