Proxy Python requests : authentification, délais et erreurs

18 min de lecture

Comment faire passer Python requests par un proxy HTTP ou SOCKS5 : le dict proxies, l'authentification identifiant/mot de passe, les variables d'environnement, les délais, et ce que ProxyError, 407 et SSLError veulent réellement dire.

Ce guide s'adresse aux développeurs qui ont besoin que Python Requests passe par un proxy et continue de fonctionner quand le proxy se comporte mal. Les exemples utilisent des hôtes fictifs et des identifiants factices. Top Proxy ne vend pas d'IP et ne distribue pas de listes gratuites ; nous comparons les services qui le font.

Les extraits visent Requests 2.34.2 sur PyPI, qui exige Python 3.10 ou plus récent. Le comportement proxy ci-dessous suit la documentation d'usage avancé de Requests. Nous avons relancé les cas clés le 14 octobre 2026 contre un montage loopback figé (Python 3.14.6, Requests 2.34.2, urllib3 2.8.0, PySocks 1.7.1, vérification TLS activée). Ce laboratoire montre le comportement du protocole seulement, pas la vitesse, les emplacements ou la qualité d'IP d'un fournisseur.

01Un exemple minimal de proxy Python requests

Chaque méthode de requête prend un dict proxies. Les clés sont le schéma de l'URL cible ; les valeurs sont l'URL du proxy :

import requests

proxies = {
    "http": "http://203.0.113.10:8080",
    "https": "http://203.0.113.10:8080",
}

r = requests.get("https://httpbin.org/ip", proxies=proxies, timeout=(3.05, 27))
print(r.status_code, r.json())

Deux détails piègent souvent. D'abord, la clé "https" pointe en général vers une URL de proxy http://. C'est correct : le client demande au proxy un tunnel CONNECT et le TLS s'exécute à l'intérieur. N'utilisez https:// à cet endroit que si votre fournisseur termine le TLS sur le port du proxy. Ensuite, écrivez l'URL du proxy avec un schéma explicite (http://, https://, socks5:// ou socks5h://) pour que le protocole soit sans ambiguïté. Requests 2.34.2 préfixe http:// à un host:port sans schéma ; ce n'est pas une URL de proxy invalide. InvalidProxyURL est levée quand la chaîne n'a toujours pas d'hôte après l'analyse, pas parce que le schéma a été omis.

httpbin.org/ip renvoie du JSON avec un champ origin, qui est l'adresse vue par le serveur. Comparez-la avec l'IP ou la plage de sortie que votre fournisseur documente pour votre forfait, et notez votre adresse directe sur Mon IP. Une adresse inchangée ne prouve pas à elle seule que le proxy a été contourné. Certains montages sortent par le même réseau que le vôtre. Si vous avez seulement besoin de savoir si un point d'accès répond, utilisez le vérificateur de proxies ou le tutoriel plus long comment vérifier qu'un proxy fonctionne.

Une clé scheme://hostname route un hôte exact autrement :

proxies = {
    "https": "http://203.0.113.10:8080",
    "https://api.internal.example": "http://198.51.100.5:3128",
}

Cette correspondance d'hôte est exacte. Elle ne s'applique pas à chaque nom sous le même domaine.

02Réglages proxy sur une Session (et le piège de l'environnement)

Une Session réutilise les connexions et centralise les défauts :

session = requests.Session()
session.proxies.update(proxies)
session.get("https://httpbin.org/ip", timeout=10)

La documentation de Requests prévient que session.proxies peut ne pas se comporter comme on l'attend. Les valeurs posées là peuvent être écrasées par les proxies de l'environnement (ce que urllib.request.getproxies() renvoie). Un HTTPS_PROXY hérité peut gagner en silence. Deux façons de rendre le choix explicite :

# Option 1: pass proxies on every call (the documented fix)
session.get(url, proxies=proxies, timeout=10)

# Option 2: stop the session from reading the environment
session.trust_env = False
session.proxies.update(proxies)

trust_env = False empêche aussi la session de lire .netrc et les variables de bundle d'AC telles que REQUESTS_CA_BUNDLE.

Ce n'est pas un avertissement théorique. Dans le montage du 14 octobre 2026, Session.proxies pointait vers un proxy loopback tandis que HTTP_PROXY / HTTPS_PROXY pointaient vers un autre. Le proxy d'environnement a reçu le GET. La même session, avec proxies= passé sur l'appel, a touché le proxy de la session. Une seconde session avec trust_env = False a utilisé Session.proxies et ignoré l'environnement. Si un script « au hasard » utilise le proxy de CI, regardez ici avant de réécrire l'URL.

03Variables d'environnement de proxy Python requests

Si vous ne passez pas proxies du tout, Requests lit les variables standard http_proxy, https_proxy, no_proxy et all_proxy. Dans un processus normal, les noms en majuscules marchent aussi. Ce n'est pas la règle HTTP de curl, où http_proxy est la variable en minuscules pour HTTP. Une exception CPython : si REQUEST_METHOD est défini (processus CGI), urllib.request.getproxies_environment() abandonne le mapping HTTP venu de HTTP_PROXY, afin qu'un en-tête client Proxy: ne puisse pas l'injecter. http_proxy en minuscules peut encore s'appliquer.

export HTTP_PROXY="http://203.0.113.10:8080"
export HTTPS_PROXY="http://203.0.113.10:8080"
export NO_PROXY="localhost,127.0.0.1,.internal.example"
python my_script.py

Sans NO_PROXY, les appels vers localhost ou des services internes peuvent passer par le proxy d'environnement et expirer. NO_PROXY ne gouverne que les proxies pris depuis l'environnement. Un hôte qui correspond à NO_PROXY peut encore être proxifié si vous passez un dict proxies= explicite qui le couvre.

Le montage a confirmé les deux côtés. Avec NO_PROXY=127.0.0.1,localhost et sans argument proxies=, le GET est allé tout droit à l'origine locale ; aucun des deux proxies du laboratoire ne l'a vu. Le même hôte, avec un dict proxies= explicite, est passé par le proxy que nous avons fourni. C'est pourquoi un bug « ça marche dans le shell, pas dans le worker » est souvent deux chemins de configuration différents, pas deux bibliothèques différentes.

D'où vient le réglageS'applique àQuand l'utiliser
Argument proxies= sur la requêteCet appel seulement, en écrasant les proxies d'environnementScripts qui doivent utiliser une sortie précise, p. ex. rotation par requête
Session.proxiesChaque appel de cette session, sauf si l'environnement l'écraseClients longue durée, idéalement avec trust_env = False
HTTP_PROXY / HTTPS_PROXY / ALL_PROXYChaque appel Requests du processus qui fait encore confiance à l'environnementOutils tiers et CI où vous ne pouvez pas modifier le code
NO_PROXYHôtes qui sautent les proxies d'environnement (un proxies= explicite peut encore les couvrir)Localhost, points d'accès de métadonnées, API internes

04Authentification proxy Python requests (identifiant et mot de passe)

La plupart des proxies payants exigent un login. Requests prend en charge l'authentification HTTP Basic pour les proxies via l'URL elle-même, http://user:***@host:port, dans le dict proxies ou dans n'importe laquelle des variables d'environnement :

import os
from urllib.parse import quote

user = quote(os.environ["PROXY_USER"], safe="")
password = quote(os.environ["PROXY_PASS"], safe="")
host = "gate.example-provider.com:7000"

proxy_url = f"http://{user}:{password}@{host}"
proxies = {"http": proxy_url, "https": proxy_url}

Chargez les identifiants depuis un gestionnaire de secrets à l'exécution. La documentation de Requests considère que les stocker dans des variables d'environnement ou des fichiers versionnés est un risque de sécurité. Encodez en pourcentage l'identifiant et le mot de passe. Requests décode les deux parties qu'il tire de l'URL, donc tout @, :, / ou # dans l'un ou l'autre doit passer par quote(..., safe=""). Sinon l'URL peut s'analyser de travers, et le proxy ne voit jamais les identifiants que vous vouliez envoyer. Après décodage, l'user-id HTTP Basic ne peut pas contenir de deux-points (RFC 7617 section 2) ; le mot de passe, si. Encoder un deux-points dans l'identifiant ne le rend pas légal : Requests le décode à nouveau en deux-points. Un deux-points supplémentaire non encodé dans le userinfo est analysé comme le début du mot de passe (alice:bob:secret devient l'utilisateur alice et le mot de passe bob:secret).

Les drapeaux de pays ou de session sticky dans l'identifiant (user-country-us-session-abc123) sont une syntaxe fournisseur, pas une fonctionnalité de Requests. Ils n'accordent pas à eux seuls une géographie ou un compte.

Vous pouvez aussi rencontrer requests.auth.HTTPProxyAuth dans des réponses plus anciennes. Il ajoute un en-tête Proxy-Authorization à l'objet requête. Dans le test loopback, il a authentifié les requêtes HTTP simples (200), mais la requête HTTPS a échoué avec un ProxyError mentionnant 407. Cela correspond à l'en-tête qui voyage sur la requête plutôt que sur le CONNECT que le proxy vérifie. Préférez les identifiants dans l'URL.

Requests ne gère que l'authentification Basic du proxy. Les proxies NTLM ou Kerberos/Negotiate ont besoin d'une bibliothèque d'auth tierce ou d'un proxy d'aide local.

Si la question que vous avez tapée était seulement « que veut dire 407 ? », ce statut a sa propre page : 407 Proxy Authentication Required. Cet article reste sur la façon dont Requests le fait remonter.

05Proxies SOCKS5 dans requests

Le support SOCKS est un extra optionnel qui tire PySocks (1.7.1 sur PyPI au moment de l'écriture) :

python -m pip install "requests[socks]"

Ensuite, les URL SOCKS fonctionnent dans le même dict proxies, identifiants compris :

proxies = {
    "http": "socks5h://user:***@203.0.113.10:1080",
    "https": "socks5h://user:***@203.0.113.10:1080",
}

Faites attention au h. Avec socks5://, la résolution DNS se fait sur votre machine et seule l'IP résultante va au proxy. Avec socks5h://, le proxy résout le nom d'hôte. C'est la même scission que curl.

Le montage l'a rendu visible sur https://example.com/. Les deux schémas ont renvoyé 200. Le serveur SOCKS a journalisé ATYP 1 (IPv4, 172.66.147.243) pour socks5:// et ATYP 3 (nom d'hôte example.com) pour socks5h://. Les appels HTTP vers 127.0.0.1 ne montrent pas la différence, parce qu'une IP est déjà une adresse. Utilisez socks5h quand vous ne voulez pas que votre résolveur local voie les lookups. Pour la comparaison de protocoles dans le langage du catalogue, voir SOCKS5 ou HTTP.

Schéma d'URL de proxyExtra nécessaireQui résout le DNSUsage typique
http://AucunLe proxy, pour le nom d'hôte que vous demandezLa plupart des passerelles HTTP(S) payantes
https://AucunLe proxyFournisseurs qui terminent le TLS sur le port du proxy
socks5://requests[socks]Votre machineProxies SOCKS où le DNS local est acceptable
socks5h://requests[socks]Le proxyProxies SOCKS, les lookups DNS restent côté proxy

Incertain de ce que parle un point d'accès ? Passez-le dans le vérificateur de proxies.

06Délai (timeout) proxy Python requests

Requests n'a pas de délai par défaut, donc un proxy coincé peut bloquer un appel pendant des minutes. Passez toujours timeout, idéalement comme un tuple (connect, read) :

r = requests.get(url, proxies=proxies, timeout=(3.05, 27))

La valeur connect couvre la connexion TCP, ce qui avec un proxy veut dire la connexion vers le proxy. La documentation suggère une valeur légèrement au-dessus d'un multiple de 3 pour s'aligner sur la retransmission TCP. La valeur read est l'écart maximal entre octets du serveur, pas un plafond sur le temps total de téléchargement. La latence dépend du fournisseur, de la sortie et de la cible, donc réglez la valeur read d'après les temps de réponse mesurés sur votre vrai point d'accès.

Un piège utile : quand le proxy lui-même n'accepte pas la connexion TCP à temps, Requests 2.34.2 a levé ProxyError en encapsulant le ConnectTimeoutError d'urllib3, pas un ConnectTimeout de premier niveau. Dans le montage, timeout=(1.0, 5) contre 192.0.2.1:8080 a produit ce wrapper. Après qu'un proxy fonctionnel se soit connecté, une origine lente avec timeout=(3.05, 1.0) a levé ReadTimeout. Attrapez ProxyError et ReadTimeout avant un ConnectionError générique, et inspectez le message ou __cause__ si vous devez distinguer « le proxy n'a jamais répondu » de « le proxy a répondu, puis le site s'est tu ».

Pour les échecs transitoires, montez un adaptateur avec des nouvelles tentatives bornées plutôt que d'écrire une boucle à la main :

from requests.adapters import HTTPAdapter
from urllib3.util import Retry

retry = Retry(total=3, backoff_factor=0.5, status_forcelist=[429, 502, 503, 504])
session.mount("https://", HTTPAdapter(max_retries=retry))
session.mount("http://", HTTPAdapter(max_retries=retry))

Les nouvelles tentatives de statut suivent allowed_methods. L'ensemble par défaut d'urllib3 2.8.0 est GET, HEAD, PUT, DELETE, OPTIONS et TRACE ; POST est exclu sauf si vous l'ajoutez. N'activez la relecture que pour les opérations sûres à envoyer deux fois. total=3 plafonne les tentatives, pas le temps d'horloge. Quand la réponse a Retry-After, urllib3 attend ce délai si respect_retry_after_header est vrai (le défaut).

Les nouvelles tentatives ne corrigeront pas un 407, une mauvaise AC, ou un trust_env qui pointe vers la mauvaise passerelle. Elles n'aident que lorsque l'échec est réellement transitoire.

07Erreurs proxy Python requests : ce que chaque exception veut dire

Ordonnez vos blocs except avec soin. ProxyError, SSLError et ConnectTimeout sous-classent tous ConnectionError, et ConnectTimeout est aussi un Timeout. Attrapez d'abord les plus spécifiques :

from requests.exceptions import (
    ProxyError, SSLError, ConnectTimeout, ReadTimeout,
    ConnectionError, InvalidProxyURL, RequestException,
)

try:
    r = session.get(url, proxies=proxies, timeout=(3.05, 27))
    r.raise_for_status()
except ProxyError as e:
    ...  # proxy unreachable, CONNECT refused, or connect-timeout to the proxy; check the message for 407
except SSLError as e:
    ...  # certificate problem; fix trust, don't disable verification
except ConnectTimeout:
    ...  # could not connect in time (more often seen without a proxy)
except ReadTimeout:
    ...  # connected, but the server went quiet
except InvalidProxyURL:
    ...  # malformed proxy URL
except ConnectionError:
    ...  # DNS failure, reset, other network errors
except RequestException:
    ...  # anything else from requests
SymptômeCause probableQuoi essayer
ProxyError sans 407 dans le messageRien n'accepte de connexions sur cet hôte/port, proxy down, un blocage réseau/liste d'autorisation, ou un délai de connexion vers le proxyVérifiez l'hôte et le port, puis testez le point d'accès dans le vérificateur de proxies ; les identifiants ne sont pas le premier suspect
ProxyError mentionnant 407 sur une URL HTTPSLe CONNECT n'emportait pas d'identifiants acceptés par le proxy : aucun envoyé, posés seulement via HTTPProxyAuth, mal encodés, mauvais format, ou forfait inactifMettez des identifiants encodés dans l'URL du proxy ; confirmez le format d'identifiant et le statut du forfait
Réponse de statut 407 sur une URL HTTPLe proxy demande des identifiants ; sur une requête envoyée sans eux, c'est juste le défiAjoutez les identifiants à l'URL du proxy ; s'ils y étaient déjà, vérifiez l'encodage et le format
Réponse de statut 401La destination, pas le proxy, veut une authentificationCorrigez l'auth du site lui-même ; la partie proxy a fonctionné
Requests ignore votre Session.proxiesLes proxies d'environnement les écrasentPassez proxies= par appel ou posez trust_env = False
InvalidSchema: Missing dependencies for SOCKS supportrequests[socks] n'est pas installépython -m pip install "requests[socks]"
SSLError: CERTIFICATE_VERIFY_FAILEDProxy interceptant ou un certificat de laboratoire/auto-signé que le bundle par défaut ne reconnaît pasPointez verify= ou REQUESTS_CA_BUNDLE vers le fichier d'AC de ce proxy
Reste bloqué indéfinimentAucun timeout poséPassez toujours un tuple (connect, read)
origin ne correspond pas à la sortie attendueProxy non appliqué pour ce schéma, NO_PROXY a correspondu alors que vous comptiez sur les proxies d'environnement, ou une route différente de celle supposéePosez les deux clés http et https ; si vous utilisez les proxies d'env, vérifiez NO_PROXY ; comparez avec l'IP/plage de sortie documentée du fournisseur

Ce qu'un test local a montré

Résultats observés des tests Requests depuis le montage proxy local contrôlé

Nous avons exécuté ces motifs contre un proxy de test loopback le 14 octobre 2026 : Python 3.14.6, Requests 2.34.2, urllib3 2.8.0, certifi 2026.07.22, PySocks 1.7.1, timeout=(3.05, 10) sauf mention, vérification TLS activée. Utilisateur factice demo ; le mot de passe contenait de la ponctuation et a été encodé en pourcentage dans les URL, puis masqué dans les journaux. Les contrôles HTTPS ont utilisé https://example.com/ plus un serveur local avec une AC de laboratoire. Les lignes ci-dessous sont des observations capturées de ce montage, pas un décompte de tests automatisés réussis. Cela montre le comportement du protocole seulement.

CasCible HTTPCible HTTPS
Pas d'identifiants proxyRéponse 407ProxyError mentionnant 407
Identifiants encodés en pourcentage dans l'URL du proxy200200 (example.com et TLS de laboratoire avec verify= pointé vers l'AC du lab)
HTTPProxyAuth seulement200ProxyError mentionnant 407
Port proxy ferméProxyError, pas de 407non testé
Auth proxy valide, le site renvoie 401Réponse 401 du sitenon testé
AC par défaut contre certificat auto-signé du labn/aSSLError: CERTIFICATE_VERIFY_FAILED ; 200 après avoir fait confiance à l'AC du lab
Session.proxies contre HTTP_PROXYLe proxy d'environnement a reçu le GETnon testé
proxies= sur l'appel, env définiLe proxy de session/ouvert a reçu le GETnon testé
trust_env = FalseSession.proxies utilisé ; env ignorénon testé
NO_PROXY correspond à l'hôteDirect vers l'origine ; aucun hit proxynon testé
proxies= explicite sur un hôte NO_PROXYQuand même proxifiénon testé
Délai de connexion vers le proxyProxyError encapsulant ConnectTimeoutErrornon testé
Délai de lecture à travers un proxy fonctionnelReadTimeoutnon testé

SOCKS5 avec identifiants encodés a renvoyé 200 pour HTTP et pour https://example.com/. Scission DNS : socks5:// a livré une adresse IPv4 au proxy ; socks5h:// a livré le nom d'hôte.

Certificats, proxies interceptants et verify

Une passerelle d'inspection TLS d'entreprise ou un proxy interceptant local re-signe le HTTPS avec sa propre autorité de certification, que Requests refuse. Faites confiance à cette AC explicitement au lieu de couper la vérification :

r = requests.get(
    url,
    proxies={"https": "http://127.0.0.1:8080"},
    verify="/path/to/proxy-ca.pem",
    timeout=10,
)

ou export REQUESTS_CA_BUNDLE=/path/to/ca.pem pour tout le processus. Convertissez d'abord un export DER en PEM. L'origine auto-signée du laboratoire a reproduit la même classe d'échec : le verify=True par défaut a levé SSLError (certificate verify failed: self-signed certificate) ; la même requête avec verify= pointé vers l'AC du lab a renvoyé 200. verify=False fait accepter à Requests n'importe quel certificat et ignorer les décalages de nom d'hôte, ce qui défait le TLS pour tout ce que ce client envoie. Ce n'est pas une correction normale pour un proxy qui « ne marche pas ».

08Proxies rotatifs en Python

Beaucoup de fournisseurs commerciaux tournent pour vous derrière un seul hôte de passerelle. Selon le tarif, la sortie peut changer par requête ou sur un intervalle de session, et un identifiant de session dans le nom d'utilisateur épingle en général une sortie un moment plutôt que d'en donner une nouvelle à chaque appel. Ces règles sont des réglages fournisseur, donc consultez leur documentation. Sticky ou rotatif couvre le langage produit. Si vous gérez vous-même une liste de points d'accès, choisissez-en un par requête et passez-le via proxies= :

import itertools

pool = itertools.cycle(
    [
        "http://user:***@203.0.113.10:8080",
        "http://user:***@203.0.113.11:8080",
    ]
)

for url in urls:
    p = next(pool)
    session.get(url, proxies={"http": p, "https": p}, timeout=(3.05, 27))

Passez le proxy par appel, puisque les proxies d'environnement peuvent écraser Session.proxies. Le type de sortie est un choix séparé : datacenter, résidentiel ou mobile. Le prix et la façon dont un site cible traite le trafic dépendent du tarif, de la cible et de la réputation de l'IP, pas du libellé de type seul. Un proxy n'accorde pas à lui seul une géographie ou une éligibilité de compte.

Avant d'acheter, confirmez que le forfait choisi prend en charge le protocole (HTTP ou SOCKS5) et la méthode d'auth (login ou liste d'autorisation d'IP) dont votre code a besoin. L'automatisation de navigateur est une autre pile ; pour les contextes Playwright, voir Proxy Playwright. Fournisseurs de notre catalogue avec des passerelles proxy :

Bright Data — proxies résidentiels et datacenter
Bright Data — proxies résidentiels et datacenter4.41442

Bright Data est un grand réseau de proxies pour la collecte de données : IP résidentielles, mobiles, ISP et datacenter dans environ 195 pays. Le trafic résidentiel peut se payer à l'usage sans abonnement, et les adresses datacenter et ISP se vendent par packs dès 10 IP. L'accès résidentiel et mobile exige une vérification d'identité.

10 pays
5,00 $US
par 1 GB
Oxylabs — proxies résidentiels et datacenter
Oxylabs — proxies résidentiels et datacenter4.0771

Oxylabs vend des proxies résidentiels, mobiles, ISP et datacenter sous un seul abonnement mensuel dès $30. Paiements acheteur : cartes, virement, AliPay, PayPal.

10 pays
0,45 $US
par 1 GB
SOAX — proxies résidentiels et mobiles
SOAX — proxies résidentiels et mobiles3.8218

SOAX vend des proxies résidentiels et mobiles rotatifs sur un pool de crédits partagé, avec datacenter et ISP dans les mêmes forfaits. Builder commence à $200/mois + TVA (200 crédits) ; le trafic Tier 1 est à $3/GB sur Builder.

85 pays
3,00 $US
par 1 GB
Decodo (Smartproxy) — proxies résidentiels et datacenter
Decodo (Smartproxy) — proxies résidentiels et datacenter4.22118

Decodo (anciennement Smartproxy) vend des proxies résidentiels et datacenter. Résidentiel : $4/GB sans forfait mensuel, ou packs mensuels dès $3.75/GB pour 3 GB. Paiements : cartes, PayPal, Alipay, Google/Apple Pay, crypto (avec limites).

83 pays
0,38 $US
par 1 GB

Comment utiliser un proxy avec Python requests ?

Passez un dict du type {"http": "http://host:port", "https": "http://host:port"} comme argument proxies. Les clés sont le schéma de l'URL cible ; les valeurs sont des URL de proxy. Préférez un schéma explicite sur ces valeurs pour ne pas mélanger HTTP et SOCKS. Un host:port normal sans schéma se voit préfixer http:// dans Requests 2.34.2 ; il n'est pas rejeté comme InvalidProxyURL.

Comment ajouter un identifiant et un mot de passe à un proxy requests ?

Placez-les dans l'URL du proxy (http://user:***@host:port), en les encodant en pourcentage avec urllib.parse.quote(value, safe=""), et chargez-les depuis un gestionnaire de secrets plutôt que de les coder en dur. Après décodage, l'user-id HTTP Basic ne peut pas contenir de deux-points (RFC 7617) ; le mot de passe, si. Ne comptez pas sur un deux-points encodé en pourcentage pour mettre un deux-points dans l'identifiant.

Pourquoi Python requests renvoie-t-il 407 Proxy Authentication Required ?

Le proxy veut des identifiants qu'il n'a pas reçus ou n'a pas acceptés. Sur une requête envoyée sans identifiants, un 407 n'est que le défi. Sinon, vérifiez l'encodage, le format d'identifiant et le statut du forfait. Les cibles HTTPS lèvent un ProxyError mentionnant 407 ; les cibles HTTP renvoient une réponse 407. Un ProxyError sans 407, par exemple depuis un port fermé, pointe vers la connectivité. HTTPProxyAuth a authentifié le HTTP dans notre laboratoire, mais pas le CONNECT HTTPS.

Requests prend-il en charge les proxies SOCKS5 ?

Oui, après python -m pip install "requests[socks]". Utilisez socks5h:// pour laisser le proxy résoudre les noms d'hôte, ou socks5:// pour les résoudre en local. Dans le laboratoire, socks5 a livré une adresse IPv4 pour example.com et socks5h a livré le nom d'hôte.

Requests utilise-t-il la variable d'environnement HTTP_PROXY ?

Oui, quand vous ne passez pas proxies : il lit http_proxy, https_proxy, all_proxy et no_proxy. Dans un processus normal, les noms en majuscules marchent aussi. Si REQUEST_METHOD est défini (CGI), urllib ignore HTTP_PROXY pour HTTP afin qu'un en-tête Proxy ne puisse pas l'injecter ; http_proxy en minuscules peut encore s'appliquer. Ce n'est pas la règle HTTP en minuscules seulement de curl. Les proxies d'environnement peuvent écraser Session.proxies, donc passez proxies par appel ou posez session.trust_env = False. NO_PROXY ne saute que les proxies d'environnement ; un dict proxies= explicite peut encore couvrir ces hôtes.

Quel timeout dois-je poser pour requests à travers un proxy ?

Posez-en toujours un ; Requests n'a pas de défaut. Partez d'un tuple comme (3.05, 27) et ajustez après avoir mesuré les temps de réponse à travers votre vrai point d'accès proxy. Un délai de connexion vers le proxy peut remonter comme ProxyError encapsulant ConnectTimeoutError ; une origine silencieuse après connexion est ReadTimeout.

Faut-il poser verify=False si le proxy casse le HTTPS ?

Non. Faites confiance à l'AC du proxy interceptant avec verify= ou REQUESTS_CA_BUNDLE. verify=False accepte n'importe quel certificat et ignore les décalages de nom d'hôte. Dans le laboratoire, une origine auto-signée a échoué à la vérification par défaut et n'a réussi qu'après que l'AC du lab a été passée à verify=.