Comment définir des en-têtes personnalisés dans un appel requests Python

PythonBeginner
Pratiquer maintenant

Introduction

Dans le monde du développement web et de la récupération de données, comprendre comment définir des en-têtes personnalisés dans les requêtes Python est une compétence cruciale. Ce tutoriel vous guidera à travers le processus d'ajout d'en-têtes personnalisés à vos requêtes Python, ouvrant un large éventail de possibilités pour le web scraping, les interactions avec les API, et bien plus encore.

Les en-têtes personnalisés vous permettent de contrôler la façon dont vos requêtes sont traitées par les serveurs web et les API. Ils peuvent vous aider à authentifier les requêtes, à spécifier les types de contenu, à gérer la mise en cache et même à imiter le comportement d'un navigateur. À la fin de ce tutoriel, vous aurez les connaissances pratiques nécessaires pour personnaliser vos requêtes HTTP afin de répondre à des exigences spécifiques.

Comprendre les en-têtes HTTP et la bibliothèque Requests

Avant de commencer à écrire du code, comprenons ce que sont les en-têtes HTTP et pourquoi ils sont importants.

Que sont les en-têtes HTTP ?

Les en-têtes HTTP sont des paires clé-valeur envoyées dans les requêtes et les réponses entre les clients et les serveurs. Ils fournissent des informations supplémentaires sur la requête ou la réponse, telles que le type de contenu, les informations d'authentification ou les informations du client.

Par exemple, lorsque vous visitez un site web, votre navigateur inclut automatiquement des en-têtes comme User-Agent (identifiant votre navigateur), Accept (spécifiant les types de contenu que vous pouvez gérer), et plus encore.

Installation de la bibliothèque Requests

La bibliothèque Python Requests simplifie le travail avec les requêtes HTTP. Assurons-nous qu'elle est installée dans notre environnement :

  1. Ouvrez un terminal dans le WebIDE et exécutez :
pip install requests

Vous devriez voir une sortie indiquant que requests est en cours d'installation ou est déjà installé :

Requirement already satisfied: requests in /usr/local/lib/python3.10/dist-packages (2.28.1)
...

Création de votre premier script Python avec Requests

Créons un script Python simple pour tester la bibliothèque requests :

  1. Cliquez sur l'icône Explorer dans la barre latérale gauche du WebIDE
  2. Faites un clic droit dans l'explorateur de fichiers et sélectionnez "New File" (Nouveau fichier)
  3. Nommez le fichier test_requests.py
  4. Ajoutez le code suivant au fichier :
import requests

## Make a simple GET request to a test website
response = requests.get('https://httpbin.org/get')

## Print the response status code
print(f"Status Code: {response.status_code}")

## Print the response headers (what the server sent back)
print("\nResponse Headers:")
for header, value in response.headers.items():
    print(f"{header}: {value}")

## Print the response content
print("\nResponse Content:")
print(response.text[:300] + "...")  ## Showing just the first 300 characters
  1. Exécutez le script en ouvrant un terminal et en exécutant :
python test_requests.py

Vous devriez voir une sortie similaire à :

Status Code: 200

Response Headers:
Date: Wed, 12 Apr 2023 10:15:23 GMT
Content-Type: application/json
Content-Length: 267
Server: gunicorn/19.9.0
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true

Response Content:
{
  "args": {},
  "headers": {
    "Accept": "*/*",
    "Accept-Encoding": "gzip, deflate",
    "Host": "httpbin.org",
    "User-Agent": "python-requests/2.28.1",
    "X-Amzn-Trace-Id": "Root=1-643..."
  },
  "origin": "123.45.67.89",
  "url": "https://httpbin.org/get"
}
...

Cette sortie montre :

  1. Le serveur a répondu avec le code d'état 200 (Succès)
  2. Les en-têtes que le serveur a renvoyés
  3. Le contenu réel de la réponse (au format JSON)

Notez que le serveur enregistre les en-têtes qu'il a reçus de nous, y compris l'en-tête User-Agent généré automatiquement qui identifie notre requête comme provenant de la bibliothèque Python requests.

Dans l'étape suivante, nous apprendrons comment personnaliser ces en-têtes pour avoir plus de contrôle sur nos requêtes.

Définition d'en-têtes personnalisés de base dans les requêtes Python

Maintenant que nous comprenons ce que sont les en-têtes HTTP et que nous avons testé la bibliothèque requests, apprenons à définir des en-têtes personnalisés dans nos requêtes.

Pourquoi définir des en-têtes personnalisés ?

Il existe plusieurs raisons de définir des en-têtes personnalisés :

  1. Authentification : De nombreuses API nécessitent des jetons d'authentification envoyés dans les en-têtes
  2. User-Agent : Modifiez la façon dont vous vous identifiez auprès des sites web
  3. Content-Type : Spécifiez le format des données que vous envoyez
  4. Accept : Indiquez les types de contenu que vous pouvez gérer
  5. Custom Headers (En-têtes personnalisés) : Certaines API nécessitent des en-têtes personnalisés spécifiques

Définition des en-têtes dans les requêtes

Créons un nouveau script Python pour nous entraîner à définir des en-têtes personnalisés :

  1. Dans le WebIDE, créez un nouveau fichier nommé custom_headers.py
  2. Ajoutez le code suivant :
import requests

## Define the URL we'll make the request to
url = 'https://httpbin.org/headers'

## Define custom headers in a dictionary
custom_headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
    'X-Custom-Header': 'Hello World',
    'Accept-Language': 'en-US,en;q=0.9'
}

## Make the request with our custom headers
response = requests.get(url, headers=custom_headers)

## Print the status code
print(f"Status Code: {response.status_code}")

## Print the response content (which shows the headers the server received)
print("\nHeaders received by server:")
print(response.json())
  1. Exécutez le script :
python custom_headers.py

Vous devriez voir une sortie similaire à :

Status Code: 200

Headers received by server:
{'headers': {'Accept': '*/*', 'Accept-Encoding': 'gzip, deflate', 'Accept-Language': 'en-US,en;q=0.9', 'Host': 'httpbin.org', 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36', 'X-Custom-Header': 'Hello World', 'X-Amzn-Trace-Id': 'Root=1-6430a123-abc123def456'}}

Que se passe-t-il ?

Dans ce script, nous avons :

  1. Créé un dictionnaire appelé custom_headers contenant trois en-têtes :

    • User-Agent : Nous l'avons modifié à partir de la valeur par défaut de Python requests pour imiter un navigateur web
    • X-Custom-Header : Un en-tête entièrement personnalisé que nous avons inventé
    • Accept-Language : Spécifie les langues préférées pour le contenu
  2. Passé nos en-têtes à requests.get() en utilisant le paramètre headers

  3. La réponse de httpbin.org/headers nous montre exactement quels en-têtes ont été reçus, confirmant que nos en-têtes personnalisés ont été envoyés avec succès

Modification des en-têtes pour un cas d'utilisation spécifique

Créons un autre exemple où nous prétendons être un appareil mobile. Cela peut être utile lors du test de sites web adaptés aux mobiles :

  1. Créez un nouveau fichier nommé mobile_headers.py
  2. Ajoutez le code suivant :
import requests

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

## Header to simulate an iPhone
mobile_headers = {
    'User-Agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 15_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.0 Mobile/15E148 Safari/604.1',
    'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8'
}

print("Making request with mobile device headers...")
response = requests.get(url, headers=mobile_headers)

## Print the response content
print(response.json())
  1. Exécutez le script :
python mobile_headers.py

Vous devriez voir une sortie similaire à :

Making request with mobile device headers...
{'headers': {'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8', 'Accept-Encoding': 'gzip, deflate', 'Host': 'httpbin.org', 'User-Agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 15_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.0 Mobile/15E148 Safari/604.1', 'X-Amzn-Trace-Id': 'Root=1-6430a456-abc123def456'}}

Cela montre que nous indiquons avec succès au serveur que nous sommes un iPhone en définissant un en-tête User-Agent spécifique.

Travailler avec les en-têtes d'authentification

L'une des utilisations les plus courantes des en-têtes personnalisés est l'authentification avec les services web et les API. De nombreuses API vous obligent à inclure des informations d'authentification dans les en-têtes de vos requêtes.

Comprendre les en-têtes d'authentification

Il existe plusieurs méthodes d'authentification courantes :

  1. API Keys (Clés API) : Jetons simples inclus dans les en-têtes ou les paramètres d'URL
  2. Basic Authentication (Authentification de base) : Nom d'utilisateur et mot de passe encodés en Base64
  3. Bearer Tokens (Jetons porteurs) : Utilisés dans l'authentification OAuth et JWT
  4. Custom Authentication (Authentification personnalisée) : Schémas d'authentification propriétaires

Explorons comment implémenter ces méthodes d'authentification avec les requêtes Python.

Authentification par clé API

De nombreuses API autorisent l'accès à l'aide de clés API. Celles-ci sont généralement incluses dans les en-têtes ou en tant que paramètres d'URL :

  1. Créez un nouveau fichier nommé api_key_auth.py
  2. Ajoutez le code suivant :
import requests

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

## Simulating an API key authentication
api_key = 'my_fake_api_key_12345'

## Add the API key to the headers
headers = {
    'X-API-Key': api_key,
    'User-Agent': 'My API Client/1.0'
}

## Make the request
response = requests.get(url, headers=headers)

## Print results
print(f"Status Code: {response.status_code}")
print("\nHeaders received by server:")
print(response.json())
  1. Exécutez le script :
python api_key_auth.py

Vous devriez voir une sortie similaire à :

Status Code: 200

Headers received by server:
{'headers': {'Accept': '*/*', 'Accept-Encoding': 'gzip, deflate', 'Host': 'httpbin.org', 'User-Agent': 'My API Client/1.0', 'X-API-Key': 'my_fake_api_key_12345', 'X-Amzn-Trace-Id': 'Root=1-6430a789-abc123def456'}}

Cela confirme que nous avons envoyé avec succès une clé API dans l'en-tête X-API-Key.

Authentification de base

L'authentification de base implique l'envoi d'un nom d'utilisateur et d'un mot de passe encodés au format base64. La bibliothèque Requests facilite cela :

  1. Créez un nouveau fichier nommé basic_auth.py
  2. Ajoutez le code suivant :
import requests

## URL that requires basic authentication
url = 'https://httpbin.org/basic-auth/user/pass'

## Method 1: Using the auth parameter (recommended)
print("Method 1: Using the auth parameter")
response = requests.get(url, auth=('user', 'pass'))
print(f"Status Code: {response.status_code}")
print(response.json())

## Method 2: Setting the Authorization header manually
print("\nMethod 2: Setting the Authorization header manually")
import base64

## Create the basic auth string: "username:password" encoded in base64
auth_string = base64.b64encode('user:pass'.encode('utf-8')).decode('utf-8')
headers = {
    'Authorization': f'Basic {auth_string}'
}

response = requests.get(url, headers=headers)
print(f"Status Code: {response.status_code}")
print(response.json())
  1. Exécutez le script :
python basic_auth.py

Vous devriez voir une sortie similaire à :

Method 1: Using the auth parameter
Status Code: 200
{'authenticated': True, 'user': 'user'}

Method 2: Setting the Authorization header manually
Status Code: 200
{'authenticated': True, 'user': 'user'}

Les deux méthodes se sont authentifiées avec succès auprès du service :

  • La méthode 1 utilise le paramètre auth intégré, ce qui est plus pratique
  • La méthode 2 montre comment l'authentification de base fonctionne "en coulisses" en créant manuellement l'en-tête Authorization

Authentification par jeton porteur

L'authentification par jeton porteur est couramment utilisée dans les systèmes basés sur OAuth 2.0 et JWT :

  1. Créez un nouveau fichier nommé bearer_auth.py
  2. Ajoutez le code suivant :
import requests

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

## Simulate a bearer token (in a real app this would come from an OAuth process)
bearer_token = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIn0.Q6CM1qIQkXA_DqyJq9MI0-mnRRCRR3c0SIM-Nul5MZs'

## Add the Authorization header with the Bearer token
headers = {
    'Authorization': f'Bearer {bearer_token}'
}

## Make the request
response = requests.get(url, headers=headers)

## Print results
print(f"Status Code: {response.status_code}")
print("\nHeaders received by server:")
print(response.json())
  1. Exécutez le script :
python bearer_auth.py

Vous devriez voir une sortie similaire à :

Status Code: 200

Headers received by server:
{'headers': {'Accept': '*/*', 'Accept-Encoding': 'gzip, deflate', 'Authorization': 'Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIn0.Q6CM1qIQkXA_DqyJq9MI0-mnRRCRR3c0SIM-Nul5MZs', 'Host': 'httpbin.org', 'X-Amzn-Trace-Id': 'Root=1-6430a901-abc123def456'}}

Cela montre une requête réussie avec un jeton porteur inclus dans l'en-tête Authorization.

Les jetons porteurs sont généralement obtenus après un processus d'authentification réussi avec un serveur OAuth 2.0, mais dans cet exemple, nous utilisons un exemple de jeton à des fins de démonstration.

Applications pratiques et bonnes pratiques

Maintenant que vous avez appris à définir différents types d'en-têtes personnalisés, explorons quelques applications pratiques et bonnes pratiques pour travailler avec les en-têtes dans des scénarios réels.

Envoi et réception de données JSON

Lorsque vous travaillez avec des API modernes, JSON est le format de données le plus courant. Voyons comment définir correctement les en-têtes pour les requêtes JSON :

  1. Créez un nouveau fichier nommé json_requests.py
  2. Ajoutez le code suivant :
import requests
import json

url = 'https://httpbin.org/post'  ## This endpoint accepts POST requests

## Data to send
data = {
    'name': 'John Doe',
    'email': 'john@example.com',
    'message': 'Hello, world!'
}

## Set appropriate headers for JSON
headers = {
    'Content-Type': 'application/json',
    'Accept': 'application/json'
}

## Method 1: Using the json parameter (recommended)
print("Method 1: Using the json parameter")
response = requests.post(url, json=data, headers=headers)
print(f"Status Code: {response.status_code}")
print(response.json()['headers'])  ## Show the headers received
print(f"\nData sent (as received by server): {response.json()['json']}")

## Method 2: Manually converting to JSON
print("\nMethod 2: Manually converting to JSON")
json_data = json.dumps(data)
response = requests.post(url, data=json_data, headers=headers)
print(f"Status Code: {response.status_code}")
print(response.json()['headers'])  ## Show the headers received
print(f"\nData sent (as received by server): {response.json()['json']}")
  1. Exécutez le script :
python json_requests.py

Vous devriez voir une sortie similaire à :

Method 1: Using the json parameter
Status Code: 200
{'Accept': 'application/json', 'Accept-Encoding': 'gzip, deflate', 'Content-Length': '72', 'Content-Type': 'application/json', 'Host': 'httpbin.org', 'X-Amzn-Trace-Id': 'Root=1-6430ab12-abc123def456'}

Data sent (as received by server): {'name': 'John Doe', 'email': 'john@example.com', 'message': 'Hello, world!'}

Method 2: Manually converting to JSON
Status Code: 200
{'Accept': 'application/json', 'Accept-Encoding': 'gzip, deflate', 'Content-Length': '72', 'Content-Type': 'application/json', 'Host': 'httpbin.org', 'X-Amzn-Trace-Id': 'Root=1-6430ab13-abc123def456'}

Data sent (as received by server): {'name': 'John Doe', 'email': 'john@example.com', 'message': 'Hello, world!'}

Notez que les deux méthodes fonctionnent, mais la méthode 1 est plus pratique car la bibliothèque Requests gère la conversion JSON pour vous.

Création d'une session réutilisable avec des en-têtes par défaut

Si vous devez effectuer plusieurs requêtes avec les mêmes en-têtes, l'utilisation d'un objet Session peut vous faire gagner du temps et rendre votre code plus propre :

  1. Créez un nouveau fichier nommé session_headers.py
  2. Ajoutez le code suivant :
import requests

## Create a session object
session = requests.Session()

## Set default headers for all requests made with this session
session.headers.update({
    'User-Agent': 'MyCustomApp/1.0',
    'Accept-Language': 'en-US,en;q=0.9',
    'X-API-Key': 'my_session_api_key'
})

## Make a request using the session - it will include our default headers
print("First request with session:")
response = session.get('https://httpbin.org/headers')
print(response.json())

## Add a custom header just for this request
print("\nSecond request with additional header:")
response = session.get('https://httpbin.org/headers',
                      headers={'X-Custom-Header': 'Just for this request'})
print(response.json())

## Original headers remain unchanged for future requests
print("\nThird request (original headers only):")
response = session.get('https://httpbin.org/headers')
print(response.json())
  1. Exécutez le script :
python session_headers.py

Vous devriez voir une sortie similaire à :

First request with session:
{'headers': {'Accept': '*/*', 'Accept-Encoding': 'gzip, deflate', 'Accept-Language': 'en-US,en;q=0.9', 'Host': 'httpbin.org', 'User-Agent': 'MyCustomApp/1.0', 'X-API-Key': 'my_session_api_key', 'X-Amzn-Trace-Id': 'Root=1-6430ab45-abc123def456'}}

Second request with additional header:
{'headers': {'Accept': '*/*', 'Accept-Encoding': 'gzip, deflate', 'Accept-Language': 'en-US,en;q=0.9', 'Host': 'httpbin.org', 'User-Agent': 'MyCustomApp/1.0', 'X-API-Key': 'my_session_api_key', 'X-Custom-Header': 'Just for this request', 'X-Amzn-Trace-Id': 'Root=1-6430ab46-abc123def456'}}

Third request (original headers only):
{'headers': {'Accept': '*/*', 'Accept-Encoding': 'gzip, deflate', 'Accept-Language': 'en-US,en;q=0.9', 'Host': 'httpbin.org', 'User-Agent': 'MyCustomApp/1.0', 'X-API-Key': 'my_session_api_key', 'X-Amzn-Trace-Id': 'Root=1-6430ab47-abc123def456'}}

L'utilisation de sessions est une bonne pratique pour plusieurs raisons :

  1. Amélioration des performances (mise en commun des connexions)
  2. En-têtes cohérents sur les requêtes
  3. Gestion automatique des cookies
  4. Possibilité d'ajouter une personnalisation par requête si nécessaire

Bonnes pratiques pour travailler avec les en-têtes

Pour conclure, voici quelques bonnes pratiques à suivre lorsque vous travaillez avec les en-têtes HTTP :

  1. Utilisez des objets Session pour plusieurs requêtes vers le même domaine
  2. Définissez correctement les en-têtes Content-Type pour les données que vous envoyez
  3. Gérez correctement l'authentification - utilisez l'authentification intégrée lorsque cela est possible
  4. Protégez les informations sensibles - ne codez pas en dur les clés API ou les jetons
  5. Suivez attentivement la documentation de l'API pour les en-têtes requis

Voici un dernier exemple qui démontre ces bonnes pratiques :

  1. Créez un nouveau fichier nommé best_practices.py
  2. Ajoutez le code suivant :
import requests
import os

## In a real application, get these from environment variables or a secure configuration
## For this example, we're keeping it simple
API_KEY = os.environ.get('API_KEY', 'default_api_key')
BASE_URL = 'https://httpbin.org'

def create_api_client():
    """Create a reusable session with default headers."""
    session = requests.Session()

    ## Set common headers
    session.headers.update({
        'User-Agent': 'MyApp/1.0',
        'X-API-Key': API_KEY,
        'Accept': 'application/json'
    })

    return session

def get_data(client, endpoint):
    """Make a GET request to the specified endpoint."""
    url = f"{BASE_URL}/{endpoint}"
    response = client.get(url)
    return response.json()

def post_data(client, endpoint, data):
    """Make a POST request with JSON data."""
    url = f"{BASE_URL}/{endpoint}"
    response = client.post(url, json=data)
    return response.json()

## Usage example
def main():
    ## Create the API client
    client = create_api_client()

    ## GET request example
    print("Making GET request...")
    get_response = get_data(client, 'headers')
    print(f"Headers sent: {get_response['headers']}")

    ## POST request example
    print("\nMaking POST request...")
    data = {'name': 'John', 'age': 30}
    post_response = post_data(client, 'post', data)
    print(f"Data received by server: {post_response['json']}")

if __name__ == '__main__':
    main()
  1. Exécutez le script :
python best_practices.py

Vous devriez voir une sortie similaire à :

Making GET request...
Headers sent: {'Accept': 'application/json', 'Accept-Encoding': 'gzip, deflate', 'Host': 'httpbin.org', 'User-Agent': 'MyApp/1.0', 'X-API-Key': 'default_api_key', 'X-Amzn-Trace-Id': 'Root=1-6430ab78-abc123def456'}

Making POST request...
Data received by server: {'name': 'John', 'age': 30}

Cet exemple démontre une approche structurée pour effectuer des requêtes HTTP avec des en-têtes personnalisés, en suivant les bonnes pratiques telles que la création de sessions réutilisables, l'organisation du code en fonctions et l'évitement des informations sensibles codées en dur.

Résumé

Dans ce tutoriel, vous avez appris à travailler avec les en-têtes personnalisés dans les requêtes Python, ce qui est une compétence essentielle pour une communication web efficace et l'intégration d'API.

Vous comprenez maintenant :

  • Ce que sont les en-têtes HTTP et pourquoi ils sont importants pour les requêtes web
  • Comment définir des en-têtes personnalisés pour des requêtes individuelles
  • Diverses méthodes d'authentification utilisant des en-têtes (clés API, authentification de base, jetons porteurs)
  • Comment travailler correctement avec les données JSON et les en-têtes de type de contenu
  • Les bonnes pratiques pour la gestion des en-têtes avec les objets session

Ces compétences vous permettront d'interagir plus efficacement avec n'importe quelle API web, d'accéder aux ressources protégées, de contrôler la façon dont vos requêtes sont traitées et de créer des applications web plus sophistiquées.

Au fur et à mesure que vous développerez vos compétences en Python, n'oubliez pas que la compréhension des bases de HTTP, telles que les en-têtes, les codes d'état et les types de contenu, vous aidera à résoudre les problèmes et à implémenter des fonctionnalités plus avancées dans vos applications web.