Gibt in meinem Skript requests.get
niemals zurück:
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)
Was könnte der mögliche Grund sein? Irgendein Mittel? Was ist das Standardzeitlimit, das get
verwendet wird?
python
get
python-requests
Nawaz
quelle
quelle
proxies={'http': 'http://222.255.169.74:8080'}
. Das könnte der Grund sein, warum es nicht ohne Zeitüberschreitung abgeschlossen wird.Antworten:
Das Standardzeitlimit ist
None
, was bedeutet, dass es wartet (hängt), bis die Verbindung geschlossen wird.Was passiert, wenn Sie einen Timeout-Wert übergeben?
quelle
None
bedeutet unendlich (oder "warten, bis die Verbindung geschlossen ist"). Wenn ich selbst eine Zeitüberschreitung habe, kehrt sie zurück!print(requests.request.__doc__)
IPython ist mehr das, wonach ich gesucht habe. Ich habe mich gefragt, welche anderen optionalen Argumente esrequest.get()
gibt.Aus der Anforderungsdokumentation :
Es passiert mir sehr oft, dass die Rückkehr von request.get () sehr lange dauert, selbst wenn die
timeout
1 Sekunde beträgt. Es gibt einige Möglichkeiten, um dieses Problem zu lösen:1. Verwenden Sie die
TimeoutSauce
interne KlasseVon: https://github.com/kennethreitz/requests/issues/1928#issuecomment-35811896
2. Verwenden Sie eine Reihe von Anfragen von Kevin Burke: https://github.com/kevinburke/requests/tree/connect-timeout
Aus der Dokumentation: https://github.com/kevinburke/requests/blob/connect-timeout/docs/user/advanced.rst
HINWEIS: Die Änderung wurde inzwischen mit dem Hauptanforderungsprojekt zusammengeführt .
3. Verwenden
evenlet
odersignal
wie bereits in der ähnlichen Frage erwähnt: Zeitüberschreitung für Python-Anforderungen. Erhalten Sie die gesamte Antwortquelle
Ich wollte ein Standard-Timeout, das einfach zu einer Reihe von Codes hinzugefügt werden kann (vorausgesetzt, das Timeout löst Ihr Problem).
Dies ist die Lösung, die ich von einem Ticket erhalten habe, das an das Repository für Anfragen gesendet wurde.
Gutschrift: https://github.com/kennethreitz/requests/issues/2011#issuecomment-477784399
Die Lösung sind die letzten paar Zeilen hier, aber ich zeige mehr Code für einen besseren Kontext. Ich verwende gerne eine Sitzung für Wiederholungsverhalten.
dann kannst du so etwas machen:
quelle
Überprüfte alle Antworten und kam zu dem Schluss, dass das Problem immer noch besteht. Auf einigen Websites können Anfragen unendlich hängen bleiben und die Verwendung von Multiprocessing scheint übertrieben zu sein. Hier ist mein Ansatz (Python 3.5+):
AKTUALISIEREN
Wenn Sie eine deprecation Warnung conn_timeout und read_timeout, Scheck nahe der Unterseite über die Verwendung erhalten DIESE Referenz für die ClientTimeout Datenstruktur zu verwenden. Eine einfache Möglichkeit, diese Datenstruktur gemäß dem verknüpften Verweis auf den obigen Originalcode anzuwenden, wäre:
quelle
Durch das Patchen der dokumentierten "Sende" -Funktion wird dies für alle Anforderungen behoben - auch in vielen abhängigen Bibliotheken und SDKs. Stellen Sie beim Patchen von Bibliotheken sicher, dass Sie unterstützte / dokumentierte Funktionen patchen, nicht TimeoutSauce. Andernfalls verlieren Sie möglicherweise stillschweigend die Wirkung Ihres Patches.
Die Auswirkungen einer fehlenden Zeitüberschreitung sind sehr schwerwiegend, und die Verwendung einer Standardzeitüberschreitung kann fast nie zu einer Unterbrechung führen, da TCP selbst auch Standardzeitüberschreitungen aufweist.
quelle
In meinem Fall liegt der Grund für "Anfragen.get kehrt nie zurück" darin, dass zuerst
requests.get()
versucht wurde, eine Verbindung zu dem mit IPv6 IP aufgelösten Host herzustellen . Wenn etwas schief gelaufen ist, um diese IPv6-IP zu verbinden und hängen zu bleiben, wird die IPv4-IP nur dann wiederholt, wenn ichtimeout=<N seconds>
das Timeout explizit festgelegt und erreicht habe.Meine Lösung besteht darin, die Python- Affen zu patchen
socket
, um IPv6 zu ignorieren (oder IPv4, wenn IPv4 nicht funktioniert). Entweder diese Antwort oder diese Antwort funktioniert für mich.Sie fragen sich vielleicht, warum der
curl
Befehl funktioniert, weil Siecurl
ipv4 verbinden, ohne auf den Abschluss von ipv6 zu warten. Sie können die Socket-Systemaufrufe mit demstrace -ff -e network -s 10000 -- curl -vLk '<your url>'
Befehl verfolgen . Für Python kann derstrace -ff -e network -s 10000 -- python3 <your python script>
Befehl verwendet werden.quelle