Dans mon script, requests.get
ne retourne jamais:
import requests
print ("requesting..")
# This call never returns!
r = requests.get(
"http://www.some-site.com",
proxies = {'http': '222.255.169.74:8080'},
)
print(r.ok)
Quelle pourrait être la ou les raisons possibles? Un remède? Quel est le délai d'expiration par défaut get
utilisé?
python
get
python-requests
Nawaz
la source
la source
proxies={'http': 'http://222.255.169.74:8080'}
. Cela pourrait expliquer pourquoi il ne se termine pas sans délai.Réponses:
Le délai d'expiration par défaut est
None
, ce qui signifie qu'il attendra (se bloque) jusqu'à ce que la connexion soit fermée.Que se passe-t-il lorsque vous passez une valeur de délai d'expiration?
la source
None
signifie infini (ou "attendez que la connexion soit fermée"). Si je passe le timeout moi-même, il revient!print(requests.request.__doc__)
en IPython est plus ce que je recherchais. Je me demandais quels étaient les autres arguments facultatifsrequest.get()
.De la documentation des demandes :
Il m'arrive souvent que requests.get () prenne beaucoup de temps à revenir même si le
timeout
est 1 seconde. Il existe plusieurs moyens de résoudre ce problème:1. Utilisez la
TimeoutSauce
classe interneDe: https://github.com/kennethreitz/requests/issues/1928#issuecomment-35811896
2. Utilisez une fourchette de requêtes de kevinburke: https://github.com/kevinburke/requests/tree/connect-timeout
Depuis sa documentation: https://github.com/kevinburke/requests/blob/connect-timeout/docs/user/advanced.rst
REMARQUE: la modification a depuis été fusionnée avec le projet Requests principal .
3. En utilisant
evenlet
ousignal
comme déjà mentionné dans la question similaire: Timeout for python requests.get réponse entièrela source
Je voulais un délai d'expiration par défaut facilement ajouté à un tas de code (en supposant que le délai d'expiration résout votre problème)
C'est la solution que j'ai choisie à partir d'un ticket soumis au référentiel pour les demandes.
crédit: https://github.com/kennethreitz/requests/issues/2011#issuecomment-477784399
La solution est les deux dernières lignes ici, mais je montre plus de code pour un meilleur contexte. J'aime utiliser une session pour le comportement de nouvelle tentative.
alors vous pouvez faire quelque chose comme ceci:
la source
Examiné toutes les réponses et est arrivé à la conclusion que le problème existe toujours. Sur certains sites, les demandes peuvent se bloquer indéfiniment et l'utilisation du multitraitement semble être excessive. Voici mon approche (Python 3.5+):
METTRE À JOUR
Si vous recevez un avertissement d'obsolescence concernant l'utilisation de conn_timeout et read_timeout, vérifiez près du bas de CETTE référence pour savoir comment utiliser la structure de données ClientTimeout. Un moyen simple d'appliquer cette structure de données par la référence liée au code d'origine ci-dessus serait:
la source
La mise à jour de la fonction "envoyer" documentée résoudra ce problème pour toutes les requêtes - même dans de nombreuses bibliothèques et sdk dépendants. Lorsque vous corrigez des bibliothèques, assurez-vous de corriger les fonctions prises en charge / documentées, et non TimeoutSauce, sinon vous risquez de perdre silencieusement l'effet de votre correctif.
Les effets de l'absence de délai d'expiration sont assez graves, et l'utilisation d'un délai d'expiration par défaut ne peut presque jamais rien casser - car TCP lui-même a également des délais d'expiration par défaut.
la source
Dans mon cas, la raison de "requests.get ne retourne jamais" est que la
requests.get()
tentative de connexion à l'hôte résolue avec ipv6 ip en premier . Si quelque chose ne va pas pour connecter cette ip ipv6 et rester bloqué, alors il réessaye ipv4 ip uniquement si je définis explicitementtimeout=<N seconds>
et atteint le délai d'expiration.Ma solution consiste à patcher le python
socket
pour ignorer ipv6 (ou ipv4 si ipv4 ne fonctionne pas), cette réponse ou cette réponse fonctionne pour moi.Vous vous demandez peut-être pourquoi la
curl
commande fonctionne, carcurl
connectez ipv4 sans attendre la fin de l'ipv6. Vous pouvez tracer les appels système de socket avec lastrace -ff -e network -s 10000 -- curl -vLk '<your url>'
commande. Pour python, lastrace -ff -e network -s 10000 -- python3 <your python script>
commande peut être utilisée.la source