Retour au blog
Les techniques de web scraping
Raluca PenciucLast updated on May 12, 20269 min read

En-têtes HTTP Web Scraping : Ne plus être bloqué

En-têtes HTTP Web Scraping : Ne plus être bloqué
En bref : les en-têtes HTTP sont généralement la raison pour laquelle votre scraper renvoie une erreur 403 alors que votre navigateur charge sans problème la même URL. Ce guide vous explique quels en-têtes les systèmes anti-bot inspectent réellement, comment capturer l'ensemble des en-têtes d'un vrai navigateur à partir des DevTools, comment les envoyer et les faire tourner correctement en Python et Node.js, et à quel moment le réglage manuel cesse d'être rentable et qu'il vaut mieux opter pour une API de scraping gérée.

La plupart des scrapers bloqués ne le sont pas à cause de leur adresse IP. Ils sont bloqués par la requête qu’ils envoient avant même que le corps de la requête ne commence. Le web scraping avec les en-têtes HTTP consiste à faire en sorte que les métadonnées de votre client ressemblent à celles d’un vrai navigateur plutôt qu’à celles d’une bibliothèque Python ou Node.js par défaut, et c’est le levier le moins coûteux et le plus sous-utilisé dont vous disposez contre la détection anti-bot.

En HTTP, un en-tête est une paire nom-valeur séparée par deux points qui contient des métadonnées sur la requête ou la réponse : l'identité du client, les langues acceptées, l'encodage, les cookies, le contexte de sécurité, etc. La référence MDN sur les en-têtes HTTP et la RFC 9110 définissent la sémantique canonique. Les systèmes de détection comparent l'ensemble d'en-têtes de votre scraper à l'empreinte digitale d'une véritable session Chrome ou Firefox, et tout décalage au niveau des valeurs, de la présence, de la casse ou de l'ordre peut signaler la requête.

Ce guide s'adresse aux ingénieurs backend, données et opérations dont les scrapers renvoient des codes 403, 429, des corps vides ou une page différente de celle affichée par le navigateur. À l'issue de ce guide, vous saurez quels en-têtes sont importants, comment les extraire de DevTools et les reproduire en Python ou Node.js, comment gérer l'ordre des en-têtes et les empreintes TLS, et quand cesser l'optimisation et déléguer la couche de requêtes à un service géré.

En-têtes HTTP Web Scraping 101 : En-têtes vs cookies, mise à jour

Commencez par bien comprendre le modèle. Un en-tête de requête est une métadonnée que votre client joint à une requête sortante : qui vous êtes, ce que vous acceptez, d’où vous venez. Un en-tête de réponse est une métadonnée que le serveur renvoie : indications de statut, type de contenu, règles de mise en cache et Set-Cookie directives.

Les cookies ne constituent pas un protocole distinct ; il s'agit d'un en-tête avec état. Le serveur les distribue via Set-Cookie, et votre client les renvoie dans un Cookie en-tête à chaque requête suivante. Conformément à la RFC 6265, cet aller-retour maintient les sessions actives, transporte les jetons d'authentification, verrouille la localisation géographique et stocke les segments A/B.

Pour le web scraping des en-têtes HTTP, les deux couches sont importantes. Si vous vous trompez sur l'une ou l'autre, votre client apparaîtra comme nouveau à chaque requête, ce qui est exactement ce que la détection des bots surveille. Notre guide sur les cookies HTTP explique les mécanismes sous-jacents.

Quels en-têtes les systèmes anti-bot surveillent-ils réellement ?

Les serveurs n'évaluent pas tous les en-têtes de la même manière. Une courte liste fait le gros du travail dans les piles de fingerprinting réelles, et les mêmes noms apparaissent chez tous les fournisseurs de détection. Les sous-titres ci-dessous couvrent ces en-têtes approximativement par ordre d'importance pour le web scraping via les en-têtes HTTP, de celui que presque tout le monde se trompe (User-Agent) jusqu'aux indices du client et aux cookies par session.

User-Agent : l'en-tête le plus vérifié et le plus falsifié

User-Agent identifie le logiciel client, le système d'exploitation et le moteur de navigation, et c'est le premier en-tête testé par les systèmes anti-bot. Les valeurs par défaut telles que python-requests/2.x ou la valeur par défaut d'axios sont bloquées instantanément, car aucun véritable visiteur ne les envoie. Le profil le plus courant dans la réalité est Chrome sous Windows ; c'est donc la cible la plus sûre à imiter.

Deux schémas échouent systématiquement. Le premier consiste à réutiliser un seul UA pour des millions de requêtes. Le second consiste à modifier manuellement un UA réel, en changeant un chiffre, pour aboutir à une version qu’aucun navigateur réel n’a jamais commercialisée. Au moment de la rédaction, vérifiez par rapport à une version actuelle de Chrome ou de Firefox plutôt que de copier une chaîne de version provenant d’un tutoriel, y compris celui-ci.

Accept, Accept-Language et Accept-Encoding

Ces trois en-têtes indiquent le type de contenu que votre client peut prendre en charge. Accept énumère les types MIME, Accept-Language répertorie les paramètres régionaux tels que en-US,en;q=0.9, et Accept-Encoding répertorie les algorithmes de compression (gzip, deflate, br). Les navigateurs réels envoient ici des valeurs riches et ordonnées, et les chaînes exactes diffèrent entre Chrome et Firefox.

Les pièges sont subtils. Une adresse IP résidentielle américaine associée à Accept-Language: ru constitue une discordance d’empreinte digitale. Envoyer br (Brotli) mais ne pas parvenir à décoder un corps Brotli ressemble tout autant à un comportement de bot. Faites correspondre Accept-Language à la géolocalisation de votre proxy, et n'indiquez que les formats de compression que votre client HTTP décompresse réellement de manière transparente.

Referer et Origin

Referer indiquent au serveur quelle page a redirigé l'utilisateur vers cette URL. Une visite sur une page produit en profondeur sans Referer semble suspect, car les vrais visiteurs proviennent généralement d’un moteur de recherche, d’une liste de catégories ou d’un lien interne. Définissez une source plausible Referer , comme une recherche Google ou la page de catégorie du site lui-même.

Origin est son cousin plus strict : les navigateurs l'ajoutent aux requêtes POST et fetch/XHR inter-origines. Si vous reproduisez un appel API que vous avez observé dans DevTools, copiez le Origin en-tête mot pour mot, sinon le serveur traitera la requête comme falsifiée.

Sec-Fetch et Client Hints (Sec-CH-UA)

Les navigateurs Chromium modernes associent une famille d'en-têtes de contexte de sécurité que les anciens guides de scraping ignorent : Sec-Fetch-Site, Sec-Fetch-Mode, Sec-Fetch-Dest, et Sec-Fetch-User. Ils indiquent si la requête correspond à une navigation de premier niveau, à une ressource intégrée ou à une requête XHR inter-origines. Le chargement direct d'une page à partir d'un nouvel onglet envoie généralement Sec-Fetch-Site: none, Sec-Fetch-Mode: navigate, et Sec-Fetch-Dest: document.

les Client Hints (Sec-CH-UA, Sec-CH-UA-Mobile, Sec-CH-UA-Platform) répètent votre profil d'agent utilisateur de manière structurée. La vérification de l'empreinte digitale est simple : si votre User-Agent indique Chrome sous Windows mais que votre Sec-CH-UA-Platform indique "macOS", vous êtes signalé. Indiquez toujours la source User-Agent, Sec-CH-UAet Sec-CH-UA-Platform à partir de la même capture de navigateur réel afin qu'ils restent cohérents en interne.

Cookies et en-têtes de session

Après la première requête, Cookie devient l'en-tête le plus révélateur de votre identité que vous envoyez. Les systèmes anti-bot l'utilisent pour déterminer si une session est active, si vous avez accepté une bannière de consentement et si votre jeton CSRF provient du même rendu que le formulaire que vous soumettez. Si vous supprimez les cookies entre les requêtes, vous apparaissez comme un tout nouveau visiteur à chaque fois.

Les en-têtes personnalisés tels que x-csrf-token, x-api-key, et Authorization apparaissent sur les points de terminaison XHR derrière les SPA modernes. Extrayez-les du code HTML ou d’une réponse JSON précédente, puis joignez-les à l’appel de données proprement dit. Sans cette étape, l’API renvoie un code 401 ou des résultats vides.

Capturez les en-têtes réels du navigateur à partir de DevTools

Cessez de deviner les valeurs des en-têtes. Ouvrez le site cible dans une session normale de Chrome ou Firefox, cliquez avec le bouton droit et choisissez Inspecter, puis passez à l'onglet Réseau. Rechargez la page, cliquez sur la première requête de document (le HTML), puis ouvrez le panneau En-têtes. La section En-têtes de requête constitue votre référence.

Deux astuces vous feront gagner du temps. Cliquez avec le bouton droit sur la requête et sélectionnez « Copier en tant que cURL » pour extraire l'appel complet, y compris les en-têtes, les cookies et le corps, dans une commande prête à être exécutée en ligne de commande. Et avant de relancer l'appel, supprimez les valeurs spécifiques à la session telles que Cookie, x-client-dataet tous les jetons CSRF à usage unique.

Validez la relecture en la pointant vers httpbin.org/headers, qui renvoie exactement ce que votre client a envoyé. Si la réponse ne correspond pas à la capture de DevTools, votre bibliothèque HTTP réécrit les données. Notre guide sur les en-têtes de réponse cURL aborde des techniques d'inspection plus approfondies.

Envoyer des en-têtes personnalisés en Python et Node.js

Le principe est le même dans tous les clients HTTP : créez un dictionnaire de noms et de valeurs d'en-têtes, joignez-le à la requête et réutilisez une session pour que les cookies persistent. Les deux sections spécifiques aux langages ci-dessous présentent les pièges qui se révèlent à grande échelle.

Python (requests et httpx)

Avec requests, transmettez un headers dict à get, et utilisez un Session pour que les cookies persistent d'un appel à l'autre :

import requests

headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
                  "AppleWebKit/537.36 (KHTML, like Gecko) "
                  "Chrome/<current> Safari/537.36",
    "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
    "Accept-Language": "en-US,en;q=0.9",
    "Accept-Encoding": "gzip, deflate, br",
    "Sec-Fetch-Site": "none",
    "Sec-Fetch-Mode": "navigate",
    "Sec-Fetch-Dest": "document",
}

with requests.Session() as s:
    s.headers.update(headers)
    r = s.get("https://httpbin.org/headers")
    print(r.json())

Le hic : requests ne préserve pas l'ordre des en-têtes de manière fiable, ce qui constitue une faiblesse connue en matière de fingerprinting. Pour le web scraping à grande échelle des en-têtes HTTP, privilégiez httpx, qui conserve l'ordre d'insertion exact de votre dictionnaire et prend en charge HTTP/2. Construisez le dictionnaire dans le même ordre que celui affiché par DevTools, et l'image du flux de données restera cohérente.

Node.js (axios et fetch)

Dans Node.js, axios et natif fetch acceptent un headers objet. Réutilisez une instance axios pour partager les valeurs par défaut, et utilisez un cookie jar (axios-cookiejar-support ou similaire) pour que les sessions perdurent d'une requête à l'autre :

import axios from "axios";

const client = axios.create({
  headers: {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) " +
                  "AppleWebKit/537.36 (KHTML, like Gecko) " +
                  "Chrome/<current> Safari/537.36",
    "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
    "Accept-Language": "en-US,en;q=0.9",
    "Sec-Fetch-Site": "none",
    "Sec-Fetch-Mode": "navigate",
    "Sec-Fetch-Dest": "document",
  },
});

const { data } = await client.get("https://httpbin.org/headers");
console.log(data);

Faites attention aux valeurs par défaut d'axios telles que X-Requested-With: XMLHttpRequest, qui divulguent la bibliothèque. Remplacez-les ou supprimez-les explicitement. Notre analyse approfondie des en-têtes axios couvre les modèles de détection et d’évitement au niveau de la couche de requête.

Ordre des en-têtes, casse et empreintes TLS

Les noms d'en-têtes ne sont pas sensibles à la casse selon la RFC, mais leur casse et leur ordre constituent en grande partie une empreinte digitale. Le véritable Chrome envoie User-Agent avec cette casse exacte dans un emplacement spécifique par rapport à Accept et Sec-Fetch-*. Python requests met traditionnellement les noms en minuscules et ne garantit pas l'ordre ; httpx conserve tout ce que vous lui fournissez ; axios est généralement fidèle mais ajoute ses propres valeurs par défaut si vous ne les supprimez pas.

Ce n'est qu'une partie du tableau. Même avec un ensemble d'en-têtes parfait, votre poignée de main TLS constitue une empreinte digitale unique. JA3 et le plus récent JA4 hachent les suites de chiffrement, les extensions et les courbes elliptiques proposées par votre client. Une pile TLS Python prétendant être Chrome mais proposant l'ordre de chiffrement d'OpenSSL est un mensonge évident ; consultez tlsfingerprint.io pour voir à quel point cela est détectable.

Mesures d'atténuation : utilisez un client compatible HTTP/2 avec des paramètres TLS réalistes (curl_cffi, tls-client en Python ; undici avec un TLS personnalisé dans Node), ou passez à un proxy furtif ou à une API gérée qui gère la couche TLS à votre place.

Faites tourner et actualisez les ensembles d'en-têtes à grande échelle

À grande échelle, la rotation des en-têtes HTTP pour le web scraping fonctionne au niveau de la session, et non au niveau de la requête. Conservez un ensemble d'en-têtes réaliste pendant toute la durée de vie de ses cookies, et ne le remplacez que lorsque vous démarrez une nouvelle identité. Le remplacement User-Agent en cours de session est en soi un signal de détection.

Constituez un pool de centaines d'ensembles d'en-têtes réels à partir des versions actuelles de Chrome, Firefox, Edge et Safari. Actualisez-le à mesure que les navigateurs sont mis à jour, sinon vous vous démarquerez en utilisant l'UA de l'année dernière. Associez la rotation des en-têtes à la rotation des proxys afin qu'aucune IP ni aucun en-tête ne devienne à lui seul une clé stable. Notre guide pour éviter les interdictions d'IP et le guide pratique sur les requêtes Python via proxy couvrent l'aspect proxy.

En-têtes de bibliothèque par défaut à supprimer avant l'envoi

Avant toute requête, vérifiez ce que votre bibliothèque envoie sans qu'on le lui demande. Indices courants :

  • User-Agent: python-requests/<version> ou l'UA par défaut d'axios
  • X-Requested-With: XMLHttpRequest provenant d'axios
  • Accept: */* au lieu d'une véritable liste MIME
  • Connection: close lorsque les navigateurs réels utilisent le keep-alive
  • Injecté par le proxy Via, X-Forwarded-For, et Forwarded

Remplacez les quatre premiers par des valeurs réalistes, et testez votre proxy par rapport à httpbin.org/headers pour détecter le dernier groupe.

Débogage des blocages basés sur les en-têtes : une liste de contrôle

La boucle de débogage pour le web scraping des en-têtes HTTP est courte. Lorsque vous obtenez un 403, un 429 ou un corps vide alors que le navigateur s'affiche correctement, suivez cette liste dans l'ordre :

  1. Comparez les en-têtes. Comparez votre capture DevTools httpbin.org/headers ligne par ligne.
  2. Remplacez l'User-Agent par une autre chaîne Chrome ou Firefox actuelle et réessayez.
  3. Vérifiez Accept-Encoding. Si vous indiquez br, assurez-vous que votre client le décompresse ; sinon, ignorez-le.
  4. Vérifiez les cookies. Assurez-vous que Cookie correspond à la session que vous avez préparée.
  5. Relancez avec cURL à partir de Copy as cURL. Si cURL fonctionne et que votre code ne fonctionne pas, la différence se trouve dans votre client. Si cURL échoue également, le problème vient de l'IP ou du TLS, et non des en-têtes.

Quand passer des en-têtes manuels à une API de scraping gérée

Le scraping web avec en-têtes HTTP manuels a ses limites. Passez à la vitesse supérieure lorsque vous rencontrez l'un des cas suivants :

  • Blocages TLS ou JA3/JA4 qui persistent malgré des en-têtes parfaits. La solution se trouve ci-dessous HTTP.
  • Une concurrence supérieure à quelques centaines de sessions, où les pools d'UA et les pots de cookies à jour deviennent un service à part entière.
  • Un coût de rotation en heures d'ingénierie qui dépasse ce qu'un point de terminaison géré facture par opération réussie.
  • Cibles difficiles derrière une gestion des bots d'entreprise qui lie les sessions à une empreinte digitale complète du navigateur.

Une API de scraping gérée ou un proxy furtif gère les en-têtes, le TLS, les adresses IP et les tentatives de reconnexion derrière un seul point de terminaison, ce qui permet à votre code de conserver la logique d'analyse. Notre guide 2026 sur le web scraping sans se faire bloquer couvre l'ensemble du processus d'escalade.

Points clés

  • Les en-têtes de bibliothèque par défaut sont le signe le plus évident. Remplacez python-requests/x.y les UA, les valeurs par défaut d'axios et X-Requested-With avant toute autre chose.
  • Capturez, n'inventez pas. Récupérez les ensembles d'en-têtes depuis DevTools ou Copy as cURL, supprimez les valeurs spécifiques à la session et validez-les par rapport à httpbin.org/headers.
  • La cohérence interne prime sur le réalisme pur. User-Agent, Sec-CH-UA, Sec-CH-UA-Platform, et Accept-Language doivent tous décrire le même navigateur, le même système d'exploitation et la même zone géographique.
  • L'ordre et le TLS sont aussi importants que les valeurs. Privilégiez httpx à requests en Python, et utilisez un client compatible TLS (ou une API gérée) lorsque l'empreinte digitale JA3/JA4 est en jeu.
  • Effectuez la rotation par session, et non par requête. Conservez un ensemble d'en-têtes pendant toute la durée de vie du cookie, actualisez le pool à mesure que les navigateurs se mettent à jour, et associez-le à une rotation des proxys.

FAQ

Pourquoi mes requêtes sont-elles toujours bloquées après avoir copié les en-têtes exacts depuis Chrome ?

Généralement parce que les en-têtes ne sont pas le seul indice. Votre poignée de main TLS (JA3/JA4), l'ordre des trames HTTP/2, la réputation de votre adresse IP et l'absence de cookies de session constituent autant d'empreintes digitales de votre client. Même des en-têtes identiques à l'octet près échouent lorsque la pile TLS sous-jacente indique « Python » au lieu de « Chrome ». Relancez la requête avec cURL : si cURL réussit et que votre code échoue, le problème se situe en dessous de la couche des en-têtes.

À quelle fréquence dois-je faire tourner les chaînes User-Agent et les ensembles d'en-têtes complets d'une requête à l'autre ?

Faites-le par session, pas par requête. Un vrai visiteur garde le même navigateur pendant toute sa visite, donc une session qui change User-Agent en cours de route est en soi suspecte. Conservez un ensemble d’en-têtes pendant toute la durée de vie de son cookie, puis choisissez-en un nouveau pour la session suivante. Actualisez le pool sous-jacent toutes les quelques semaines, à mesure que Chrome et Firefox publient de nouvelles versions stables.

Dois-je toujours définir des en-têtes HTTP si j'utilise un navigateur sans interface graphique comme Playwright ou Puppeteer ?

Oui, en partie. Un navigateur sans interface utilisateur envoie automatiquement des en-têtes réalistes, y compris Sec-CH-UA et Sec-Fetch-*, ce qui vous permet d'éviter la plupart des manipulations manuelles. Vous devez toutefois remplacer le mode sans interface User-Agent (qui inclut souvent HeadlessChrome), définir une valeur plausible Accept-Language pour la localisation géographique de votre proxy, et désactiver le navigator.webdriver indicateur via un plugin stealth ou un indicateur de lancement.

Une API de scraping gérée ou un proxy intelligent peut-il gérer automatiquement les en-têtes HTTP à ma place ?

Oui. Les API de scraping gérées et les réseaux de proxys furtifs sélectionnent un ensemble d'en-têtes réaliste par cible, l'associent à une adresse IP résidentielle et à un profil TLS, puis font tourner le tout de manière synchronisée. Vous envoyez l'URL cible, ils renvoient le HTML ou le JSON. Le compromis réside entre le coût par requête et le temps d'ingénierie nécessaire pour créer et maintenir votre propre pile d'en-têtes, de proxys et de reconnaissance d'empreintes.

Comment savoir si un blocage est dû aux en-têtes, à l'adresse IP ou à une empreinte TLS ?

Isolez une variable à la fois. Commencez par rejouer votre requête exacte à partir curl --resolve à partir de la même adresse IP ; si cURL réussit, le problème se situe au niveau des en-têtes ou de l'ordre de votre client HTTP. Ensuite, passez à une autre adresse IP résidentielle avec les mêmes en-têtes ; si le blocage disparaît, c'est l'adresse IP qui a été signalée. Si aucune de ces solutions ne fonctionne, la poignée de main TLS est probablement en cause.

Conclusion

Le scraping des en-têtes HTTP n'est pas la partie la plus glamour de la création d'un scraper, mais c'est celle qui offre le meilleur retour sur investissement pour un minimum d'effort. Capturez les en-têtes réels du navigateur, envoyez-les dans l'ordre utilisé par le navigateur, et conservez User-Agent, Sec-CH-UAet Accept-Language en veillant à la cohérence interne, effectuez la rotation par session plutôt que par requête, et supprimez les paramètres par défaut de la bibliothèque qui trahissent l'automatisation. Cet ensemble d'habitudes permet d'éliminer la plupart des erreurs 403 et 429 faciles à résoudre avant même d'avoir recours à un proxy.

Au-delà de cela, le réglage manuel se heurte à un mur. Les empreintes JA3/JA4, la gestion des bots d'entreprise et la forte concurrence repoussent le travail sous la couche des en-têtes, et c'est le moment idéal pour arrêter de tout faire soi-même et laisser un service géré s'en charger. Si votre pile en est là, l'API Scraper de WebScrapingAPI gère les en-têtes, les profils TLS, les adresses IP résidentielles et les tentatives de reconnexion derrière un point de terminaison unique, ce qui vous permet de conserver la logique d'analyse et d'abandonner la course à l'armement des empreintes. Commencez par là lorsque les en-têtes manuels cessent d'être l'option la moins coûteuse.

À propos de l'auteur
Raluca Penciuc, Développeur full-stack @ WebScrapingAPI
Raluca PenciucDéveloppeur full-stack

Raluca Penciuc est développeuse Full Stack chez WebScrapingAPI ; elle conçoit des robots de collecte de données, améliore les techniques de contournement et recherche des moyens fiables de réduire le risque de détection sur les sites cibles.

Commencez à créer

Prêt à faire évoluer votre système de collecte de données ?

Rejoignez plus de 2 000 entreprises qui utilisent WebScrapingAPI pour extraire des données Web à l'échelle de l'entreprise, sans aucun coût d'infrastructure.