Das Python-Anforderungsmodul ist einfach und elegant, aber eines nervt mich. Es ist möglich, eine request.exception.ConnectionError mit einer Nachricht wie der folgenden zu erhalten:
Max retries exceeded with url: ...
Dies bedeutet, dass Anforderungen mehrmals versuchen können, auf die Daten zuzugreifen. Diese Möglichkeit wird jedoch nirgendwo in den Dokumenten erwähnt. Beim Betrachten des Quellcodes habe ich keinen Ort gefunden, an dem ich den Standardwert (vermutlich 0) ändern könnte.
Ist es also möglich, die maximale Anzahl von Wiederholungsversuchen für Anforderungen festzulegen?
python
python-requests
Kirill Zaitsev
quelle
quelle
requests.get(url, max_retries=num_max_retries, dely_between_retries=3))
just.get
undjust.post
in github.com/kootenpv/justAntworten:
Es ist die zugrunde liegende
urllib3
Bibliothek, die die Wiederholung durchführt. Verwenden Sie alternative Transportadapter, um eine andere maximale Anzahl von Wiederholungsversuchen festzulegen :Das
max_retries
Argument nimmt eine Ganzzahl oder einRetry()
Objekt an . Letzteres gibt Ihnen eine genaue Kontrolle darüber, welche Arten von Fehlern wiederholt werden (ein ganzzahliger Wert wird in eineRetry()
Instanz umgewandelt, die nur Verbindungsfehler behandelt; Fehler nach dem Herstellen einer Verbindung werden standardmäßig nicht behandelt, da dies zu Nebenwirkungen führen kann). .Alte Antwort vor der Freigabe von Anfragen 1.2.1 :
Die
requests
Bibliothek macht dies nicht wirklich konfigurierbar und beabsichtigt dies auch nicht (siehe diese Pull-Anfrage ). Derzeit (Anforderungen 1.1) ist die Anzahl der Wiederholungsversuche auf 0 festgelegt. Wenn Sie den Wert wirklich auf einen höheren Wert festlegen möchten, müssen Sie diesen Wert global festlegen:Diese Konstante ist nicht dokumentiert; Verwenden Sie es auf eigene Gefahr, da zukünftige Versionen die Vorgehensweise ändern können.
Update : und das hat sich geändert; In Version 1.2.1 wurde die Option zum Festlegen des
max_retries
Parameters für dieHTTPAdapter()
Klasse hinzugefügt, sodass Sie jetzt alternative Transportadapter verwenden müssen (siehe oben). Der Monkey-Patch-Ansatz funktioniert nicht mehr, es sei denn, Sie patchen auch dieHTTPAdapter.__init__()
Standardeinstellungen (sehr wenig empfohlen).quelle
session.mount('http://', HTTPAdapter(max_retries=10))
für alle http-Verbindungen tun . Das gleiche mit https funktioniert dann für alle https-Verbindungen.http://
undhttps://
die minimalen Präfixe sind, lesen Sie die Dokumentation, auf die die Antwort verweist .HTTPAdapter(max_retries=5)
nur für bestimmte Szenarien funktioniert. Von Anfragen doc ,Note, this applies only to failed DNS lookups, socket connections and connection timeouts, never to requests where data has made it to the server. By default, Requests does not retry failed connections.
um Kraft Wiederholungs für alle Statuscodes, siehe @ datashaman Antwort unten.Retry()
, um zu ändern, welche Fehlerszenarien wiederholt werden.Dies ändert nicht nur die max_retries, sondern ermöglicht auch eine Backoff-Strategie, die Anforderungen an alle http: // Adressen für einen bestimmten Zeitraum in den Ruhezustand versetzt, bevor sie es erneut versuchen (insgesamt 5 Mal):
Gemäß Dokumentation
Retry
: Wenn der backoff_factor ist 0,1 , dann sleep () wird tief und für [0,1s, 0,2s, 0,4s, ...] zwischen den Wiederholungen. Es wird auch ein erneuter Versuch erzwungen, wenn der zurückgegebene Statuscode 500 , 502 , 503 oder 504 lautet .Verschiedene andere Optionen
Retry
für eine detailliertere Steuerung:MaxRetryError
eine Antwort ausgelöst oder eine Antwort mit einem Antwortcode im Bereich 3xx zurückgegeben werden soll.NB : raise_on_status ist relativ neu und hat es noch nicht in eine Version von urllib3 oder Anfragen geschafft.DasSchlüsselwortargument raise_on_status scheint es in Python Version 3.6 höchstens in die Standardbibliothek geschafft zu haben.Verwenden Sie status_forcelist, um Anforderungen für bestimmte HTTP-Statuscodes erneut auszuführen . Beispielsweise versucht status_forcelist = [503] den Statuscode 503 erneut (Dienst nicht verfügbar).
Standardmäßig wird der Wiederholungsversuch nur unter folgenden Bedingungen ausgelöst:
TimeoutError
HTTPException
ausgelöst (von http.client in Python 3 sonst httplib ). Dies scheinen HTTP-Ausnahmen auf niedriger Ebene zu sein, z. B. URL oder Protokoll, die nicht korrekt gebildet wurden.SocketError
ProtocolError
Beachten Sie, dass dies alles Ausnahmen sind, die den Empfang einer regulären HTTP-Antwort verhindern. Wenn eine regelmäßige Antwort generiert wird, wird kein erneuter Versuch durchgeführt. Ohne die status_forcelist zu verwenden wird auch eine Antwort mit Status 500 nicht wiederholt.
Um es auf eine Weise zu verhalten, die für die Arbeit mit einer Remote-API oder einem Webserver intuitiver ist, würde ich das obige Code-Snippet verwenden, das Wiederholungsversuche für die Status 500 , 502 , 503 und 504 erzwingt , die alle auf dem nicht ungewöhnlich sind Web und (möglicherweise) wiederherstellbar bei einer ausreichend großen Backoff-Periode.
BEARBEITET :
Retry
Klasse direkt aus urllib3 importieren .quelle
Seien Sie vorsichtig, Martijn Pieters Antwort ist nicht für Version 1.2.1+ geeignet. Sie können es nicht global festlegen, ohne die Bibliothek zu patchen.
Sie können dies stattdessen tun:
quelle
Nachdem ich ein bisschen mit einigen der Antworten hier zu kämpfen hatte, fand ich eine Bibliothek namens Backoff , die für meine Situation besser funktionierte. Ein einfaches Beispiel:
Ich würde weiterhin empfehlen, die native Funktionalität der Bibliothek zu testen. Wenn Sie jedoch auf Probleme stoßen oder eine umfassendere Kontrolle benötigen, ist Backoff eine Option.
quelle
requests
, also funktioniert das perfekt!Ein sauberer Weg, um eine höhere Kontrolle zu erlangen, könnte darin bestehen, das Wiederholungsmaterial in eine Funktion zu packen und diese Funktion mithilfe eines Dekorateurs abrufbar zu machen und die Ausnahmen auf die Whitelist zu setzen.
Ich habe das gleiche hier erstellt: http://www.praddy.in/retry-decorator-whitelisted-exceptions/
Wiedergabe des Codes in diesem Link:
quelle