Retour au blog
Guides
Mihnea-Octavian Manolache27 janvier 202310 min de lecture

Comment utiliser les en-têtes HTTP avec Axios pour éviter la détection

Comment utiliser les en-têtes HTTP avec Axios pour éviter la détection

Comment fonctionne la communication HTTP

Avant d'entrer dans le détail de la définition d'un en-tête HTTP, je pense qu'il est important d'avoir au moins une vue d'ensemble du fonctionnement du protocole HTTP. Comme vous le savez sans doute déjà, le protocole de transfert hypertexte (HTTP) est le fondement sur lequel repose le Web aujourd'hui. De manière générale, il permet le transfert d'informations entre un serveur et ses clients. Le déroulement concret de cet échange d'informations se présente comme suit :

  • Le client ouvre une nouvelle connexion TCP
  • Il envoie un message au serveur, appelé requête HTTP
  • Le serveur reçoit et interprète la requête
  • Il renvoie ensuite un message au client, appelé « réponse HTTP »
  • Le client lit le message et poursuit ou ferme la connexion
Illustration of an HTTP request showing method, URL, protocol version, and request headers

L'élément important sur lequel nous allons nous concentrer aujourd'hui est le message, en particulier celui envoyé par le client. Pour que la communication entre le serveur et le client soit efficace, les messages doivent être formatés conformément au protocole HTTP. En ce qui concerne la requête HTTP, les éléments qui composent le message sont les suivants :

La méthode décrit ce que nous voulons effectuer avec notre requête (si nous voulons recevoir, envoyer, mettre à jour des informations, etc.)

  • Le chemin, l'adresse URL que nous essayons d'atteindre
  • La version du protocole HTTP que nous utilisons
  • Les en-têtes HTTP, qui servent à envoyer des informations supplémentaires et des métadonnées en plus de notre requête
  • Le corps, dans le cas où nous utilisons une méthode qui envoie des informations au serveur (comme une requête POST)

Que sont les en-têtes HTTP Axios et comment fonctionnent-ils ?

En termes simples, les en-têtes HTTP sont des champs qui transmettent des informations supplémentaires et des métadonnées au message. Encore une fois, par message, nous entendons la requête lorsqu'elle est envoyée par le client et la réponse lorsqu'elle est envoyée par le serveur. Ainsi, le serveur et le client peuvent tous deux transmettre et recevoir des en-têtes. Par exemple, supposons que vous souhaitiez ouvrir une connexion persistante avec le serveur. Par défaut, les connexions HTTP sont fermées après chaque requête. Pour éviter cela, il vous suffit de transmettre l'en-tête `Keep-Alive`.

En ce qui concerne les en-têtes HTTP avec Axios, il n’y a vraiment rien de particulier. Comme nous l’avons vu, Axios est un client HTTP et nous avons déjà établi que les clients HTTP peuvent envoyer et recevoir des en-têtes.

Pourquoi Axios est un excellent client HTTP pour JavaScript

Maintenant que nous avons un aperçu du fonctionnement du HTTP, parlons des « clients ». JavaScript offre plusieurs options pour « interagir par programmation » avec un serveur via HTTP. Parmi les choix les plus populaires, on trouve `axios`, `node-fetch` et `got`.

Les avis divergent au sein de la communauté JavaScript quant au choix de l’outil à utiliser. Bien sûr, chaque bibliothèque présente de nombreux avantages et inconvénients, mais j’ai moi-même choisi Axios après avoir effectué un simple test de vitesse entre les trois.

Voici le script que j’ai utilisé pour tester la vitesse :

// index.js

import { get_timing, array_sum } from './helpers.js'

import got from 'got'

import axios from 'axios'

const CALLS = 5

const send = async () => {

   const res = {}

  

   let start = process.hrtime()

   await got('https://httpbin.org/')

   const g = get_timing(start)

   res.got = g

   start = process.hrtime()

   await axios.get('https://httpbin.org/')

   const a = get_timing(start)

   res.axios = a

   start = process.hrtime()

   await fetch('https://httpbin.org/')

   const f = get_timing(start)

   res.fetch = f

   return res

}

let test_results = {

   got: [],

   axios: [],

   fetch: []

}

let avg = {}

console.log(`[i] Process started with ${CALLS} iterations.`)

for (let i = 0; i<=CALLS; i++) {

   let r = await send()

   Object.entries(test_results).map(([key, value]) => test_results[key].push(r[key]))

}

Object.entries(test_results).forEach(([key, value]) => {

       console.log(`\n[+] ${key}`)

       console.log(`    [i] Average: ${array_sum(value)/value.length}`)

       console.log(`    [i] Values: ${value}`)

       avg[key] = array_sum(value)/value.length

   }

)

console.log(`\n🚀🚀🚀 WINNER: ${Object.keys(avg).reduce((key, v) => avg[v] < avg[key] ? v : key)}  [${CALLS} calls sent] 🚀🚀🚀`)

Et voici les fonctions « helper » :

// helpers.js

export const get_timing = (start) => {

   const NS_PER_SEC = 1e9

   const NS_TO_MS = 1e6

   const diff = process.hrtime(start)

   return (diff[0] * NS_PER_SEC + diff[1]) / NS_TO_MS

}

export const array_sum = (array) => {

   return array.reduce((accumulator, value) => {

     return accumulator + value

   }, 0)

}

J'ai effectué des tests avec 5, 10, 20 et 30 requêtes envoyées avec chaque bibliothèque, à raison de 10 itérations à chaque fois. Voici un aperçu des résultats :

Bar chart comparing average request times for different HTTP clients such as fetch, Axios, and Got

Par itération, j’entends le nombre d’exécutions du script, en utilisant cette formule bash, qui génère un fichier .txt contenant les résultats de chaque itération :

~ » for i in {1..10}

do

node got.js > "${i}.txt"

echo "${i} done"

done

Comme vous le verrez en consultant le tableau des résultats détaillés, les temps varient pour chaque lot et Axios n'est parfois pas le plus rapide. Dans l'ensemble, cependant, Axios a obtenu un temps moyen de 387 millisecondes, soit une demi-seconde plus rapide que ses concurrents. Got et Fetch ont affiché un temps de réponse très similaire, d'environ 435 millisecondes en moyenne. Cela dit, si la vitesse est importante pour votre projet, Axios est peut-être le meilleur client HTTP pour vous.

Comment envoyer des en-têtes HTTP avec Axios

Je trouve personnellement que l'apprentissage par la pratique donne des résultats presque instantanés. Maintenant que nous disposons à la fois des connaissances et des outils pour envoyer des en-têtes HTTP, commençons à travailler sur un petit projet. Dans cette section, nous allons créer un nouveau projet Node, installer Axios et l'utiliser pour envoyer des en-têtes HTTP à un serveur.

Configurer le projet

Avant de continuer, assurez-vous que votre machine dispose des éléments suivants :

Astuce : vous pouvez vérifier si Node JS est installé en tapant la commande suivante dans votre terminal :

~ » node -v  

v19.3.0

Créons maintenant un nouveau dossier et ouvrons-le dans notre IDE. Si vous utilisez une machine de type UNIX (Mac ou Linux), vous pouvez créer un nouveau répertoire par programmation, depuis votre terminal, en tapant la commande suivante :

~ » mkdir axios_project && cd axios_project 

~ » npm init -y

~ » npm i axios

~ » touch index.js

~ » code .

Ces commandes vont :

  • Créer un nouveau répertoire (nommé « axios_project ») et y accéder
  • Initialiser un nouveau projet Node JS à l'intérieur du répertoire
  • Installer `axios` dans votre projet
  • Créer un nouveau fichier « index.js »
  • Ouvrir votre IDE sur le projet actuel

Code à apprendre

Il existe en fait plusieurs façons d'envoyer des en-têtes HTTP avec Axios. Par exemple, vous pouvez utiliser un objet de configuration comme décrit ici, ou vous pouvez utiliser les méthodes d'instance, qui fusionneront automatiquement la configuration que vous passez avec la configuration de l'instance. Vous pouvez également utiliser l'objet `axios.defaults.headers.common` pour définir des en-têtes par défaut pour toutes les requêtes Axios.

Notez également qu’Axios est un client HTTP basé sur les promesses. Cela signifie que nous devrons soit l’attendre à l’intérieur d’une fonction asynchrone, soit résoudre la réponse.

En gardant ces deux aspects à l'esprit, commençons par un peu de code concret. Nous allons travailler dans le fichier « index.js ». Pour plus de commodité, récapitulons ce que nous devons faire au préalable :

  • Importer `axios` dans notre fichier
  • Définir un objet de configuration qui contiendra nos en-têtes
  • Transmettre la configuration à `axios` afin d’effectuer une requête
  • Afficher la réponse dans notre terminal

#1 : Envoyer une requête GET à l'aide de l'objet de configuration

import axios from "axios"

const config = {

   method: 'GET',

   url: 'https://httpbin.org/headers',

   headers: {

       'HTTP-Axios-Headers': 'This is my custom header.'

   }

}

axios(config)

   .then((response) => {

       console.log(response)

   })

   .catch((err) => {

       console.log(err)

   })

L'envoi d'en-têtes HTTP avec Axios est on ne peut plus simple. Pour exécuter ce script, il suffit de lancer la commande suivante dans votre terminal :

~ » node index.js  

{

  status: 200,

  statusText: 'OK',

  headers: ...,

  config: ...,

  request: ...,

  data: {

    headers: {

      'Accept': 'application/json, text/plain, */*',

      'Accept-Encoding': 'gzip, compress, deflate, br',

      'Host': 'httpbin.org',

      'Http-Axios-Headers': 'This is my custom header.',

      'User-Agent': 'axios/1.2.2',

      'X-Amzn-Trace-Id': 'Root=1-63b54d94-7656f02113483dfa036c476c'

    }

  }

}

La réponse complète est assez volumineuse et suit ce schéma. Cependant, ce qui nous intéresse principalement, ce sont les `données`, qui contiennent la réponse réelle que nous avons reçue du serveur. Examinez maintenant la réponse ci-dessus. Rappelez-vous que nous avons envoyé un en-tête personnalisé `Http-Axios-Headers` au serveur et, comme vous pouvez le voir, le serveur l'a bien reçu.

#2 : Envoyer une requête POST à l'aide de l'alias de méthode

import axios from "axios"

const data = {

   'foo':'bar'

}

const config = {

   headers: {

       'HTTP-Axios-Headers': 'This is my custom header.'

   }

}

axios.post('http://httpbin.org/post', data, config)

   .then(response => console.log(response.data))

   .catch(err => console.log(err))

Remarquez que pour envoyer une requête POST, j'ai ajouté un nouvel objet `data` à notre script et j'ai également modifié l'URL. À présent, si vous exécutez le script, vous constaterez que voici les données reçues du serveur :

{

  args: {},

  data: '{"foo":"bar"}',

  files: {},

  form: {},

  headers: {

    Accept: 'application/json, text/plain, */*',

    'Accept-Encoding': 'gzip, compress, deflate, br',

    'Content-Length': '13',

    'Content-Type': 'application/json',

    Host: 'httpbin.org',

    'Http-Axios-Headers': 'This is my custom header.',

    'User-Agent': 'axios/1.2.2',

    'X-Amzn-Trace-Id': 'Root=1-63b5508a-3a86493f087662d3169e80ee'

  },

  json: { foo: 'bar' },

  origin: '49.12.221.20',

  url: 'http://httpbin.org/post'

}

Comment utiliser les en-têtes HTTP dans Axios pour le web scraping

Si vous prévoyez d'utiliser Axios pour le web scraping, veuillez noter que la plupart des sites web disposent de règles de protection qui bloquent les requêtes provenant de logiciels automatisés (y compris les web scrapers).

L'utilisation d'en-têtes HTTP, en particulier l'en-tête `User-Agent`, peut être une technique utile pour éviter la détection lors du web scraping. L'en-tête User-Agent identifie le navigateur client et le système d'exploitation auprès du serveur, et les serveurs web peuvent fournir un contenu différent ou bloquer les requêtes en fonction de ces informations. En configurant l'en-tête User-Agent, vous pouvez imiter un navigateur web courant, augmentant ainsi vos chances de contourner certains mécanismes de détection.

Voici un exemple d'utilisation de l'en-tête User-Agent avec Axios pour éviter la détection lors du web scraping :

import axios from "axios"

axios.defaults.headers.common['User-Agent'] = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3'

axios({

   method: 'GET',

   url: 'https://httpbin.org/get',

}).then(response => {

   console.log(response.data)

});

Notez que cette fois-ci, j'ai utilisé l'option config defaults d'Axios, qui applique l'en-tête à toutes les requêtes à venir. Dans cet exemple, l'en-tête User-Agent est configuré pour imiter le navigateur Chrome sur un système d'exploitation Windows 10. Vous pouvez essayer d'utiliser différentes valeurs User-Agent ou divers en-têtes pour voir ce qui fonctionne le mieux pour votre cas d'utilisation spécifique.

Il convient de noter que si la modification de l'en-tête User-Agent peut vous aider à éviter la détection dans certains cas, ce n'est pas une méthode infaillible, et les serveurs web peuvent toujours être en mesure d'identifier que vous utilisez un outil de web scraping. Il est donc judicieux d'utiliser une combinaison de techniques pour éviter la détection et rester dans les limites des conditions d'utilisation du site web.

Conclusions

L'utilisation d'en-têtes HTTP avec Axios (ou avec n'importe quel autre client HTTP d'ailleurs) peut améliorer l'efficacité de la communication entre un serveur et un client. De plus, cela peut même vous aider à éviter la détection lorsque vous développez un scraper web. D'ailleurs, chez WebScrapingAPI, nous utilisons divers agents utilisateurs comme l'une des techniques d'évasion de base.

Bien sûr, la détection ne se limite pas aux agents utilisateurs, mais c'est un bon point de départ. Voici un tutoriel intéressant sur la manière d'éviter que votre adresse IP ne soit bannie lors du web scraping, qui vous aidera à mieux comprendre le fonctionnement des techniques d'évasion.

Par ailleurs, saviez-vous que Web Scraping API vous permet de définir des en-têtes personnalisés pour vos requêtes ? Si ce n'est pas le cas, découvrez-en plus ici.

À propos de l'auteur
Mihnea-Octavian Manolache, Développeur Full Stack @ WebScrapingAPI
Mihnea-Octavian ManolacheDéveloppeur Full Stack

Mihnea-Octavian Manolache est ingénieur Full Stack et DevOps chez WebScrapingAPI, où il développe des fonctionnalités pour les produits et assure la maintenance de l'infrastructure qui garantit le bon fonctionnement de la plateforme.

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.