---
title: "Gérer les requêtes qui échouent en Python"
slug: retry-failed-requests-python
date: 2025-06-10T09:34:22+00:00
modified: 2025-11-04T08:49:13+00:00
permalink: https://brightdata.fr/blog/donnees-web/retry-failed-requests-python
type: blog
---

[ Blog ](https://brightdata.fr/blog "Blog") / [Données Web](https://brightdata.fr/blog/donnees-web)







 [Données Web](https://brightdata.fr/blog/donnees-web)

# Gérer les requêtes qui échouent en Python

Apprenez à gérer les requêtes HTTP qui échouent en Python avec des stratégies de relance efficaces et une logique personnalisée.

 9 min de lecture





 [ ![Jacob Nulty](https://media.brightdata.fr/2024/12/Jacob-Nulty-50x50.jpg) ](https://brightdata.com/blog/authors/jake-nulty)

 [Jake Nulty

Technical Writer

 ](https://brightdata.com/blog/authors/jake-nulty)





 ![Managing Failed Requests in Python blog image](https://media.brightdata.fr/2025/02/Managing-Failed-Requests-in-Python-blog-image.svg)





Lorsque l’on utilise le protocole HTTP, les requêtes qui échouent sont une réalité inévitable à laquelle il faut faire face. Dans le domaine du développement web, un statut 200 indique une *bonne réponse*. Cependant, nous n’obtenons pas toujours un 200, et ce guide vous aidera à comprendre comment gérer ces codes d’état autres que 200.

Selon [Mozilla](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status), les codes de statut peuvent être répartis dans les catégories suivantes :

- **100-199**: Réponses informatives
- **200-299**: Réponses positives
- **300-399**: Messages de redirection
- **400-499**: Messages d’erreur du client
- **500-599**: Messages d’erreur du serveur

## <a></a>Que sont les codes d’état ?

Les [codes d’erreur](/blog/proxy-101/proxy-error-codes) sont importants. Lors de la création de programmes côté client tels que les scanners de sites web, nous devons principalement nous concentrer sur les codes d’état de l’ordre de 400+ et 500+. Les codes dans les 400 couvrent généralement les erreurs côté client telles que les problèmes d’authentification, les limitations de débit, les dépassements de délai et la tristement célèbre erreur 404 : Fichier introuvable. Les codes de plus de 500 correspondent généralement à des problèmes de serveur.

Depuis des décennies, Mozilla documente les normes de développement web du [W3C](https://www.w3.org/) et de l’[IETF](https://www.ietf.org/). Vous trouverez ci-dessous une liste de codes d’erreur courants que vous pourriez rencontrer. Cette liste n’est pas exhaustive. Ces erreurs proviennent de la [documentation officielle](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status#client_error_responses) de Mozilla. En fonction de votre site cible, vos codes peuvent différer légèrement, mais la logique devrait rester la même.

**Code de statut****Signification****Description**400Mauvaise demandeVérifiez le format de votre demande401Non autoriséVérifiez votre clé API403InterditVous ne pouvez pas accéder à ces données404Non trouvéLe site ou le point de terminaison n’existe pas408Délai d’attente de la demandeLa demande a expiré, réessayez429Trop de demandesRalentissez vos demandes500Erreur de serveur interneErreur générique du serveur, demande de réessai501Non mise en œuvreLe serveur ne prend pas encore en charge cette fonction502Mauvaise passerelleÉchec de la réponse d’un serveur en amont503Service indisponibleLe serveur est temporairement hors service, réessayer plus tard504Délai d’attente de la passerelleLe délai d’attente d’un serveur en amont a expiré## <a></a>Stratégies de réessai

Lors de la mise en œuvre d’un mécanisme de relance, vous pouvez utiliser des bibliothèques prédéfinies telles que HTTPAdapter et Tenacity. Selon le cas, vous pouvez même écrire votre propre logique de relance.

En règle générale, nous voulons une limite de tentatives et une stratégie pour revenir en arrière. Nous avons besoin d’une limite pour ne pas être pris dans une boucle infinie de tentatives. Nous devons nous retirer petit à petit afin de respecter le serveur hôte. Lorsque vos demandes arrivent trop vite, elles vous bloquent ou submergent le serveur.

- **Limites de réessais**: Vous devez fixer une limite. Après X tentatives, votre scraper abandonnera.
- **Algorithme de backoff**: Celui-ci est relativement simple. Il s’agit de commencer par un petit backoff et de l’augmenter à chaque nouvel essai. Nous voulons commencer par 0,3, puis passer à 0,6, 1,2 et ainsi de suite.

**Nous voulons réessayer nos demandes jusqu’à une certaine limite. Après chaque échec, nous voulons attendre un peu plus longtemps.**

## <a></a>Adaptateur HTTPA

Avec HTTPAdapter, nous devons configurer trois choses : `total`, `backoff_factor`, et `status_forcelist`. `allowed_methods` n’est pas vraiment une exigence, mais il rend notre code plus sûr en aidant à définir nos conditions de réessai. Dans le code ci-dessous, nous utilisons [httpbin](https://httpbin.org/) pour forcer automatiquement une erreur et déclencher notre logique de réessai.

```none
import requests
from requests.adapters import HTTPAdapter
from urllib3.util.retry import Retry

#create a session
session = requests.Session()

#configure retry settings
retry = Retry(
    total=3,                  #maximum retries
    backoff_factor=0.3,       #time between retries (exponential backoff)
    status_forcelist=(429, 500, 502, 503, 504), #status codes to trigger a retry
    allowed_methods={"GET", "POST"}
)

#mount the adapter with our custom settings
adapter = HTTPAdapter(max_retries=retry)
session.mount("http://", adapter)
session.mount("https://", adapter)

#actually make a request with our retry logic
try:
    print("Making a request with retry logic...")
    response = session.get("https://httpbin.org/status/500")
    response.raise_for_status()
    print("✅ Request successful:", response.status_code)
except requests.exceptions.RequestException as e:
    print("❌ Request failed after retries:", e)

```

Une fois l’objet `Session` créé, nous procédons comme suit :

- Créez un objet `Retry` et définissez les éléments suivants :
    - `total`: limite maximale pour la relance d’une demande.
    - `backoff_factor`: Temps d’attente entre les tentatives. Ce facteur s’ajuste de manière exponentielle au fur et à mesure que le nombre de tentatives augmente.
    - `status_forcelist`: Une liste de mauvais codes d’état. Tout code figurant dans cette liste déclenchera automatiquement une nouvelle tentative.
- Créer un objet `HTTPAdapter` avec notre variable `retry`: `adapter = HTTPAdapter(max_retries=retry)`.
- Une fois l’`adaptateur` créé, nous le montons sur les méthodes HTTP et HTTPS à l’aide de `session.mount().`

Lorsque vous exécutez ce code, nos trois tentatives`(total=3`) s’exécutent et vous obtenez le résultat suivant.

```none
Making a request with retry logic...
❌ Request failed after retries: HTTPSConnectionPool(host='httpbin.org', port=443): Max retries exceeded with url: /status/500 (Caused by ResponseError('too many 500 error responses'))
```

## <a></a>Ténacité

Vous pouvez également utiliser [Tenacity](https://tenacity.readthedocs.io/en/latest/), une bibliothèque de relance open source populaire pour Python. Elle n’est pas limitée à HTTP, mais elle nous offre un moyen expressif et compréhensible d’implémenter les tentatives.

Vous devez d’abord l’installer.

```none
pip install tenacity

```

Une fois installé, nous créons un *décorateur* et l’utilisons pour envelopper une fonction de requête. Avec notre décorateur `@retry`, nous ajoutons les arguments `stop`, `wait` et `retry`.

```none
import requests
from tenacity import retry, stop_after_attempt, wait_exponential, retry_if_exception_type, RetryError

#define a retry strategy
@retry(
    stop=stop_after_attempt(3),  #retry up to 3 times
    wait=wait_exponential(multiplier=0.3),  #exponential backoff
    retry=retry_if_exception_type(requests.exceptions.RequestException),  #retry on request failures
)

def make_request():
    print("Making a request with retry logic...")
    response = requests.get("https://httpbin.org/status/500")
    response.raise_for_status()
    print("✅ Request successful:", response.status_code)
    return response

# Attempt to make the request
try:
    make_request()
except RetryError as e:
    print("❌ Request failed after all retries:", e)

```

La logique et les paramètres sont très similaires à notre premier exemple avec HTTPAdapter.

- `stop=stop_after_attempt(3)`: Ceci indique à `tenacity` d’abandonner après 3 tentatives infructueuses.
- `wait=wait_exponential(multiplier=0.3)` utilise la même attente que précédemment. Il recule également de manière exponentielle, comme précédemment.
- `retry=retry_if_exception_type(requests.exceptions.RequestException)` indique à `tenacity` d’utiliser cette logique à chaque fois qu’une `RequestException` se produit.
- `make_request()` effectue une requête vers notre point d’accès à l’erreur. Elle reçoit tous les traits du décorateur que nous avons créé au-dessus d’elle.

Lorsque vous exécutez ce code, vous obtenez un résultat similaire.

```none
Making a request with retry logic...
Making a request with retry logic...
Making a request with retry logic...
❌ Request failed after all retries: RetryError[<Future at 0x75e762970760 state=finished raised HTTPError>]
```

## <a></a>Construisez votre propre mécanisme de réessai

Vous pouvez également créer votre propre mécanisme de relance. Lorsqu’il s’agit de code personnalisé, c’est souvent la meilleure approche. Avec une quantité de code relativement faible, nous pouvons obtenir le même effet que celui obtenu avec ces bibliothèques.

Dans le code ci-dessous, nous devons importer `sleep` pour notre backoff exponentiel. Nous définissons à nouveau notre configuration : `total`, `backoff_factor` et `bad_codes`. Nous utilisons ensuite une boucle `while` pour maintenir notre logique de réessai. `Tant que` nous avons encore des essais et que nous n’avons pas réussi, nous tentons la requête.

```none
import requests
from time import sleep

#create a session
session = requests.Session()

#define our retry settings
total = 3
backoff_factor = 0.3
bad_codes = [429, 500, 502, 503, 504]

#try counter and success boolean
current_tries = 0
success = False

#attempt until we succeed or run out of tries
while current_tries < total and not success:
    try:
        print("Making a request with retry logic...")
        response = session.get("https://httpbin.org/status/500")
        if response.status_code in bad_codes:
            raise requests.exceptions.HTTPError(f"Received {response.status_code}, triggering retry")
        print("✅ Request successful:", response.status_code)
        success = True
    except requests.exceptions.RequestException as e:
        print(f"❌ Request failed: {e}, retries left: {total-current_tries}")
        sleep(backoff_factor)
        backoff_factor = backoff_factor * 2
        current_tries+=1
```

La logique réelle est ici gérée par une simple boucle `while.`

- Si `response.status_code` fait partie de notre liste de `bad_codes`, nous levons une exception.
- Si une demande n’aboutit pas, nous
    - Imprime un message d’erreur sur la console.
    - `sleep(backoff_factor)` attend avant d’envoyer la demande suivante.
    - `backoff_factor = backoff_factor * 2` double notre `backoff_factor` pour le prochain essai.
    - Nous incrémentons `current_tries` pour ne pas rester indéfiniment dans la boucle.

Voici la sortie de notre logique de réessai personnalisée.

```none
Making a request with retry logic...
❌ Request failed: Received 500, triggering retry, retries left: 3
Making a request with retry logic...
❌ Request failed: Received 500, triggering retry, retries left: 2
Making a request with retry logic...
❌ Request failed: Received 500, triggering retry, retries left: 1
```

## <a></a>Dépasser les blocages

Dans la nature, certains sites vont vous bloquer. La meilleure pratique consiste à toujours [utiliser un proxy pour les requêtes Python](/blog/proxy-101/proxy-with-python-requests). Avec un proxy, votre demande passe par une machine différente. Cela permet de protéger votre identité et d’éviter que votre adresse IP ne soit bloquée par votre site cible. Nous disposons même d’un [guide détaillé](/blog/proxy-101/how-to-bypass-an-ip-ban) sur la manière de contourner les blocages d’IP. Nos [proxys résidentiels](/proxy-types/residential-proxies) sont conçus pour vous permettre de surmonter ces difficultés.

## <a></a>Conclusion

Vous savez maintenant comment gérer les échecs des requêtes HTTP en Python. Que vous écriviez un scraper, un client API ou des outils d’automatisation, vous savez comment gérer ces problèmes. Pour éviter toutes sortes d’échecs de requêtes, nous avons développé des produits tels que l’[API Web Unlocker](/products/web-unlocker) et le [Scraping Browser](/products/scraping-browser). Ces outils gèrent automatiquement les mesures anti-bots, les [défis CAPTCHA](/blog/donnees-web/what-is-a-captcha) et les blocages d’IP, garantissant ainsi un scrapping web efficace et sans faille, même pour les sites web les plus difficiles.

Inscrivez-vous maintenant et commencez votre essai gratuit dès aujourd’hui.



Contacter ventesEssai gratuit![google social icon](/wp-content/themes/brightdata/assets/images/ic_google.svg)









 Table des matières







Dedicated Scraper APIs &amp; No-Code Scrapers

Over 1000 scrapers for all popular domains. Simplify your web scraping.

[See pricing](/pricing/web-scraper "See pricing")

Just want data? Skip scraping.

Hundreds of ready-to-use datasets from all popular domains.

[See pricing](/pricing/datasets "See pricing")







 [ ](https://news.ycombinator.com/submitlink?t=G%C3%A9rer+les+requ%C3%AAtes+qui+%C3%A9chouent+en+Python&u=https://brightdata.fr/blog/donnees-web/retry-failed-requests-python) [ ](https://www.linkedin.com/shareArticle?mini=true&title=G%C3%A9rer+les+requ%C3%AAtes+qui+%C3%A9chouent+en+Python&url=https://brightdata.fr/blog/donnees-web/retry-failed-requests-python) [ ](http://www.reddit.com/submit?title=G%C3%A9rer+les+requ%C3%AAtes+qui+%C3%A9chouent+en+Python&url=https://brightdata.fr/blog/donnees-web/retry-failed-requests-python)







##  Vous pourriez aussi être intéressé par

 [ ![OpenHuman with Bright Data](https://media.brightdata.fr/2026/09/OpenHuman-with-Bright-Data.png) ](https://brightdata.fr/blog/ai/openhuman-with-bright-data "Accès Web Prêt pour la Production dans OpenHuman via le CLI Bright Data")

 [AI



 ![Antonello Zanini](https://media.brightdata.fr/2022/12/Antonello-Zanini-2-50x50.jpg)

Antonello Zanini

Technical Writer





### Accès Web Prêt pour la Production dans OpenHuman via le CLI Bright Data

Intégrez le CLI Bright Data avec OpenHuman pour permettre un accès web prêt pour la production et la collecte de données pour les agents IA.



 09-Sep-2026

 14 min de lecture

 ](https://brightdata.fr/blog/ai/openhuman-with-bright-data)

 [ ![Multimodal Web Scraping with MiniMax](https://media.brightdata.fr/2026/09/Multimodal-Web-Scraping-with-MiniMax.png) ](https://brightdata.fr/blog/donnees-web/multimodal-web-scraping-with-minimax "Scraping Web Multimodal avec MiniMax")

 [Données Web



 ![Antonello Zanini](https://media.brightdata.fr/2022/12/Antonello-Zanini-2-50x50.jpg)

Antonello Zanini

Technical Writer





### Scraping Web Multimodal avec MiniMax

Associez Bright Data Web Unlocker avec la vision MiniMax M3 pour extraire des données structurées à partir d’images et de captures d’écran de pages web.



 09-Sep-2026

 5 min de lecture

 ](https://brightdata.fr/blog/donnees-web/multimodal-web-scraping-with-minimax)

 [ ![The 10 Best CLI Tools for Codex in 2026](https://media.brightdata.fr/2026/08/The-10-Best-CLI-Tools-for-Codex-in-2026.png) ](https://brightdata.fr/blog/ai/best-cli-tools-for-codex "Les 10 meilleurs outils CLI pour Codex en 2026 – Testés & Classés")

 [AI



 ![Daniel Shashko](https://media.brightdata.fr/2022/04/Daniel-Shashko-2-50x50.png)

Daniel Shashko

Web Data &amp; AI Expert





### Les 10 meilleurs outils CLI pour Codex en 2026 – Testés &amp; Classés

Les 10 outils CLI qui rendent Codex plus rapide et plus capable, en commençant par le Bright Data CLI pour un accès web réel depuis l’intérieur du sandbox.



 06-Sep-2026

 24 min de lecture

 ](https://brightdata.fr/blog/ai/best-cli-tools-for-codex)
