Chaque ingénieur de crawler a déjà eu cette conversation. Un site qui fonctionnait hier renvoie désormais un 403. Le même code, le même proxy, les mêmes en-têtes, et quelque part, en silence, un système a décidé que votre trafic n'était pas humain. L'instinct pousse à chercher la seule chose qui aurait cassé. La réalité, c'est que rien n'a cassé. La détection s'est améliorée.

Les systèmes anti-bot modernes ne sont pas des gardiens. Ce sont des moteurs de probabilité. Chaque requête est évaluée sur des dizaines de surfaces de signal indépendantes, et un score composite unique décide si vous passez, si vous êtes ralenti en douceur, si l'on vous présente un défi, ou si l'on vous renvoie une réponse empoisonnée. Comprendre ce score (ce qui l'alimente, comment les poids évoluent, et où se trouvent réellement les gains faciles pour l'évasion) fait toute la différence entre un crawler qui survit un trimestre et un crawler qui survit une décennie.

Cet article propose la vue au niveau des systèmes. Pas une liste d'en-têtes à usurper. Pas un « cinq proxies à essayer ». Une carte du territoire, telle que nous l'expliquons en interne chez Crawlbase quand un nouvel ingénieur rejoint l'équipe plateforme.

Les trois surfaces de détection

La détection des bots se produit sur trois couches, et elles ne partagent pas de vocabulaire commun. Une empreinte qui passe la première couche peut échouer sur la deuxième. Une session qui passe les deux peut échouer sur la troisième à sa dix-huitième requête. Les couches sont, en gros :

  • L'empreinte de la couche transport : ce que votre handshake TLS révèle de la pile sous-jacente
  • L'inspection de la couche protocole : ce que votre comportement HTTP dit du client
  • La modélisation comportementale : ce à quoi ressemble votre session dans le temps

Elles sont évaluées indépendamment puis combinées statistiquement. Nous allons parcourir chacune d'elles.

L'empreinte TLS

Le premier signal arrive avant même que votre requête HTTP ne soit analysée. Lorsque votre client ouvre une connexion TLS, il envoie un paquet ClientHello qui énumère les suites de chiffrement qu'il prend en charge, les extensions qu'il annonce, les courbes elliptiques qu'il préfère, et l'ordre de tous ces éléments. Cet ordre est déterminé par l'implémentation : OpenSSL produit une empreinte, BoringSSL une autre, le crypto/tls de Go une troisième, la pile Chrome une quatrième. JA4 hache les composants pertinents en une seule chaîne.

FIG. 01 La structure d'un hash JA4. Chaque segment encode une facette différente du handshake.

La conséquence : si vous effectuez une requête depuis la bibliothèque requests de Python via un proxy résidentiel, le proxy fournit une magnifique IP résidentielle, mais l'empreinte TLS annonce « OpenSSL via Python 3.11 » à quiconque est à l'écoute. Le système de détection n'a pas besoin de regarder votre IP, vos en-têtes ou votre comportement. Le handshake seul lui dit ce que vous êtes.

Note

Le contournement populaire, qui consiste à patcher requests pour utiliser une liste de suites de chiffrement à la Chrome, échoue pour la même raison qu'il réussit : tous les crawlers le font désormais. Les fournisseurs anti-bot maintiennent des inventaires d'empreintes « Chrome mais en réalité Python ». L'incohérence entre le user-agent revendiqué et le vrai handshake est elle-même un signal.

L'inspection du profil HTTP

Une fois passée la couche TLS, c'est la requête HTTP elle-même qui est interrogée. Pas le contenu : la forme. Les vrais navigateurs envoient les en-têtes dans un ordre précis. Chrome envoie :method avant :authority ; Firefox inverse deux des entrées de moindre priorité. HTTP/2 introduit un ordonnancement des frames et une priorisation des flux qui varient selon le client.

Voici à quoi ressemble réellement une empreinte HTTP/2 pour un détecteur :

JSON
{
 "akamai_hash": "1:65536;3:1000;4:6291456;6:262144|15663105|0|m,s,a,p",
 "h2_settings": {
 "HEADER_TABLE_SIZE": 65536,
 "INITIAL_WINDOW_SIZE": 6291456,
 "MAX_HEADER_LIST_SIZE": 262144
 },
 "header_order": [":method", ":authority", ":scheme", ":path"],
 "pseudo_headers": "m,a,s,p", // Chrome canonical
 "frame_priority": [256, 255, 254, 253, 252]
}

Ce bloc suffit à identifier « Chrome 122 sur macOS » avec une grande confiance, indépendamment de la chaîne user-agent. Le hash Akamai, en particulier, est le standard de fait pour l'empreinte HTTP/2 et il est vérifié par pratiquement tous les grands CDN.

Le piège ici est plus subtil qu'à la couche TLS. Vous pouvez faire tourner les IP toute la journée ; vous pouvez changer de user-agent à chaque requête. Mais si votre client HTTP/2 négocie toujours la même INITIAL_WINDOW_SIZE quel que soit le navigateur que vous prétendez être, vous échouerez au contrôle de cohérence bien avant d'échouer au contrôle d'empreinte.

L'objectif n'est pas d'éviter les blocages. L'objectif est de rendre votre système antifragile face à eux. Extrait de notre guide d'ingénierie interne

Les signaux comportementaux

La troisième surface est celle qui croît avec le temps et qui est, de loin, la plus difficile à imiter de façon convaincante à grande échelle. Les systèmes de détection construisent un modèle de ce à quoi ressemble une session. Les vrais utilisateurs naviguent. Ils cliquent en arrière. Ils ouvrent un lien dans un nouvel onglet, le laissent quarante secondes, puis le ferment. Ils demandent favicon.ico au premier accès et plus jamais ensuite. Ils échouent parfois à charger une feuille de style et la demandent deux fois. Le timing entre leurs requêtes présente une gigue qui suit une distribution reconnaissable : log-normale dans la plupart des mesures.

Les crawlers, surtout ceux de production réglés pour le débit, ne font presque rien de tout cela. Nous demandons l'article. Nous extrayons les données. Nous passons à autre chose. Nous ne naviguons pas. Nous ne restons pas inactifs. Nous ne cliquons pas sur des publicités qui ne nous intéressent pas.

Production tip

Si les intervalles entre les requêtes de votre crawler ont un coefficient de variation inférieur à 0,3, vous êtes visiblement automatisé, même avec des empreintes parfaites. Les vrais utilisateurs se situent autour de 0,8 à 1,4. La solution n'est pas d'ajouter des pauses aléatoires ; c'est de modéliser les temps d'arrivée comme un processus stochastique et d'y échantillonner.

Le modèle de probabilité conjointe

Voici ce que nous avons mis le plus de temps à intérioriser, et la raison pour laquelle la plupart des conseils « anti-détection » vieillissent mal : les trois couches ne sont pas évaluées indépendamment avec des seuils. Elles sont combinées.

Un pipeline de détection moderne produit quelque chose comme ceci :

Python
def verdict(request, session) -> Verdict:
 tls_score = score_tls(request.handshake) # 0.0 – 1.0
 http_score = score_http(request.profile) # 0.0 – 1.0
 behavior_score = score_session(session) # 0.0 – 1.0

 # Weights are tuned per-customer, per-route, per-hour.
 composite = (
 0.30 * tls_score
 + 0.25 * http_score
 + 0.45 * behavior_score
 )

 if composite > 0.85: return Verdict.BLOCK
 if composite > 0.60: return Verdict.CHALLENGE
 if composite > 0.40: return Verdict.THROTTLE
 return Verdict.ALLOW

Trois choses découlent de cette structure, que la plupart des ingénieurs manquent.

Premièrement, vous n'avez pas besoin de gagner sur chaque surface. Un scraper avec une signature TLS légèrement décalée, des en-têtes un peu étranges et un excellent comportement de session peut obtenir un score inférieur à celui d'un scraper aux TLS et en-têtes parfaits mais aux schémas de session évidents. Le score comportemental est le plus fortement pondéré dans presque tous les systèmes modernes que nous avons inspectés.

Deuxièmement, les seuils évoluent. Le même score composite qui laissait passer le trafic à 2 h UTC peut le mettre au défi à 11 h. Le même score qui autorise sur la page de catalogue public peut bloquer sur l'API de paiement. Traiter le système comme statique est à l'origine de la plupart des pannes « ça marchait hier ».

Troisièmement, et c'est l'aperçu stratégique, les blocages ne sont pas le pire des dénouements. Un défi vous donne un retour. Un blocage vous donne un retour. C'est dans le palier du ralentissement que l'intégrité des données meurt en silence. Vous recevez des réponses ; elles ont l'air correctes ; mais les données de prix sont subtilement perturbées, les niveaux de stock sont périmés, et vous découvrez trois semaines plus tard que 12 % de votre jeu de données est empoisonné. Concevoir pour les blocages est facile. Concevoir pour détecter que vous avez été silencieusement déclassé, voilà la partie difficile.

Concevoir pour le cas antifragile

La plupart des travaux d'ingénierie de l'évasion cherchent à être invisibles. Nous en sommes venus à croire que c'est le mauvais objectif. L'invisibilité est une cible mouvante entretenue par un adversaire disposant de plus de ressources que vous. La résilience est l'objectif : construire un système dont les performances se dégradent élégamment lorsqu'il est bloqué, qui se rétablit automatiquement quand les conditions changent, et qui fait remonter un signal honnête sur sa propre qualité de données.

Concrètement, cela implique plusieurs choses dans notre infrastructure :

  1. Une diversité d'empreintes multicouche. Pas une seule imitation de Chrome, mais une population d'imitations, échantillonnée de façon appropriée. Un pool de proxies n'est pas une liste d'IP ; c'est une distribution conjointe sur (IP, pile TLS, profil HTTP, géolocalisation).
  2. Un scoring en temps réel de notre propre trafic. Nous traitons chaque requête sortante comme un tirage dans une distribution inconnue, et nous mesurons la distribution des réponses. Si p(200) sur une route donnée tombe sous la valeur de référence, cette route est automatiquement mise en quarantaine pour un crawl de diagnostic avant que le trafic de production ne reprenne.
  3. Une validation adverse. Nous scrapons périodiquement du contenu connu pour être bon et vérifions que ce que nous récupérons correspond à ce que nous attendions. L'écart entre l'attendu et l'observé est un bien meilleur indicateur de santé que les codes de statut HTTP.
Why this works

Les fournisseurs anti-bot optimisent pour attraper le scraper médian. Le scraper médian est bruyant : même empreinte sur des millions de requêtes, aucune modélisation comportementale, aucune validation. Un crawler qui est statistiquement indiscernable du trafic humain sur les dimensions que mesure le détecteur n'a pas besoin d'être invisible. Il lui suffit d'être quelconque.

À quoi ressemblent les chiffres

Pour rendre cela concret : sur notre propre infrastructure, au cours du dernier trimestre, sur un échantillon des 500 domaines les plus crawlés, nous avons observé à peu près ce qui suit.

  • Les clients à empreinte unique (bibliothèques Python/Node par défaut) ont atteint un taux de blocage de 47 % au cours des 100 premières requêtes contre une route protégée par Cloudflare.
  • Les clients à empreinte correspondante sans modélisation comportementale ont atteint 22 %.
  • Les clients à empreinte correspondante avec modélisation comportementale et timing adaptatif par route ont atteint 3,1 %.
  • La même population passée par la couche de routage intelligent de Crawlbase a atteint 0,4 %.

L'amélioration de la couche deux à la couche trois est celle qui compte. Le modèle comportemental n'est pas marginal. C'est la différence entre un crawler qui exige une surveillance constante et un crawler qui tourne sans surveillance pendant des mois.

Intégré à Crawlbase

Le chiffre de 0,4 % ci-dessus, c'est notre couche de routage intelligent qui assure la diversité d'empreintes et la modélisation comportementale décrites dans cette section, sans que vous ayez à en maintenir quoi que ce soit.

Récapitulatif

Points clés

  • La détection des bots est une probabilité conjointe sur trois surfaces indépendantes. Vous n'avez pas besoin de gagner sur chacune. Vous devez seulement ne perdre gravement sur aucune.
  • Le signal comportemental est le plus fortement pondéré dans les systèmes modernes. Les heures passées à perfectionner les empreintes TLS rapportent moins qu'un après-midi passé à modéliser un comportement de session réaliste.
  • Le ralentissement est plus dangereux que le blocage. Un blocage vous signale que quelque chose ne va pas. Un ralentissement empoisonne silencieusement votre jeu de données.
  • Concevez pour la résilience, pas pour l'invisibilité. L'invisibilité est une course aux armements que vous finirez par perdre. La résilience produit des effets cumulés.
  • Mesurez votre propre qualité de données, pas seulement vos codes de statut. Un 200 OK est nécessaire mais pas suffisant. La forme de la réponse est le vrai signal.

L'évasion anti-bot consiste, au fond, moins à battre le système qu'à comprendre à quel jeu le système joue réellement. Les systèmes sont plus intelligents qu'ils ne l'étaient il y a cinq ans. Ils le seront encore davantage dans cinq ans. Les équipes qui réussissent sont celles qui cessent de traiter la détection comme un mur à escalader et commencent à la traiter comme une contrainte à contourner par la conception, de la même façon que vous concevriez autour de la latence réseau, de la charge de la base de données ou de toute autre propriété de l'univers physique dans lequel vous opérez.

Le web n'est pas le chaos. Il a une structure. Nous la cartographions. Vous construisez avec.

Commencer à construire

Crawlez n'importe quel site à grande échelle, sans combattre l'infrastructure.

Crawlbase gère les proxies, les empreintes et les CAPTCHA afin que votre équipe livre des pipelines de données au lieu de maintenir la plomberie de crawl. 1 000 requêtes gratuites, sans carte requise.

En libre-service · Sans appel commercial requis · Volumes de crawl entreprise disponibles