712 Stimmen

Richtiger Weg, um try/except mit dem Python-Requests-Modul zu verwenden?

versuchen:
    r = requests.get(url, params={'s': sache})
außerordentliche requests.ConnectionError als e:
    print(e)

Ist das korrekt? Gibt es eine bessere Möglichkeit, dies zu strukturieren? Wird dies alle meine Bedürfnisse abdecken?

1303voto

Jonathon Reinhart Punkte 123962

Schauen Sie sich die Ausnahmedokumentation an. Kurz gesagt:

Bei einem Netzwerkproblem (z.B. DNS-Fehler, abgelehnte Verbindung usw.) wird Requests eine ConnectionError-Ausnahme auslösen.

Bei einer seltenen ungültigen HTTP-Antwort wird Requests eine HTTPError-Ausnahme auslösen.

Wenn eine Anforderung abläuft, wird eine Timeout-Ausnahme ausgelöst.

Wenn eine Anforderung die konfigurierte Anzahl von maximalen Redirections überschreitet, wird eine TooManyRedirects-Ausnahme ausgelöst.

Alle Ausnahmen, die Requests explizit auslöst, erben von requests.exceptions.RequestException.

Um Ihre Frage zu beantworten, was Sie zeigen, wird nicht alle Eventualitäten abdecken. Sie werden nur Verbindungsfehler abfangen, nicht solche, die ablaufen.

Was zu tun ist, wenn Sie die Ausnahme abfangen, liegt wirklich am Design Ihres Skripts/Ihrer Anwendung. Ist es akzeptabel, das Programm zu beenden? Können Sie weitermachen und es erneut versuchen? Wenn der Fehler katastrophal ist und Sie nicht weitermachen können, dann können Sie Ihr Programm abbrechen, indem Sie SystemExit (eine schöne Möglichkeit, sowohl einen Fehler auszugeben als auch sys.exit aufzurufen) auslösen.

Sie können entweder die Basisklassen-Ausnahme abfangen, die alle Fälle behandeln wird:

try:
    r = requests.get(url, params={'s': thing})
except requests.exceptions.RequestException as e:  # Dies ist die richtige Syntax
    raise SystemExit(e)

Oder Sie können sie separat abfangen und unterschiedliche Dinge tun.

try:
    r = requests.get(url, params={'s': thing})
except requests.exceptions.Timeout:
    # Vielleicht für einen erneuten Versuch einrichten oder in einer Wiederholungsschleife fortfahren
except requests.exceptions.TooManyRedirects:
    # Teilen Sie dem Benutzer mit, dass die URL falsch war und versuchen Sie es mit einer anderen
except requests.exceptions.RequestException as e:
    # katastrophaler Fehler. Abbruch.
    raise SystemExit(e)

Wie Christian bemerkte:

Wenn Sie möchten, dass HTTP-Fehler (z.B. 401 Unauthorized) Ausnahmen auslösen, können Sie Response.raise_for_status aufrufen. Das wird einen HTTPError auslösen, wenn die Antwort ein HTTP-Fehler war.

Ein Beispiel:

try:
    r = requests.get('http://www.google.com/nothere')
    r.raise_for_status()
except requests.exceptions.HTTPError as err:
    raise SystemExit(err)

Wird folgendes ausgeben:

404 Client Error: Not Found for url: http://www.google.com/nothere

196voto

jouell Punkte 2769

Eine zusätzliche Empfehlung, um explizit zu sein. Es scheint am besten zu sein, von spezifisch zu allgemein den Stapel von Fehlern abzuarbeiten, um den gewünschten Fehler zu erfassen, so dass die spezifischen nicht vom allgemeinen verdeckt werden.

url='http://www.google.com/blahblah'

try:
    r = requests.get(url,timeout=3)
    r.raise_for_status()
except requests.exceptions.HTTPError as errh:
    print ("Http-Fehler:",errh)
except requests.exceptions.ConnectionError as errc:
    print ("Fehler bei der Verbindung:",errc)
except requests.exceptions.Timeout as errt:
    print ("Zeitüberschreitungsfehler:",errt)
except requests.exceptions.RequestException as err:
    print ("OOps: Etwas anderes",err)

Http-Fehler: 404 Client-Fehler: Nicht gefunden für URL: http://www.google.com/blahblah

vs

url='http://www.google.com/blahblah'

try:
    r = requests.get(url,timeout=3)
    r.raise_for_status()
except requests.exceptions.RequestException as err:
    print ("OOps: Etwas anderes",err)
except requests.exceptions.HTTPError as errh:
    print ("Http-Fehler:",errh)
except requests.exceptions.ConnectionError as errc:
    print ("Fehler bei der Verbindung:",errc)
except requests.exceptions.Timeout as errt:
    print ("Zeitüberschreitungsfehler:",errt)     

OOps: Etwas anderes 404 Client-Fehler: Nicht gefunden für URL: http://www.google.com/blahblah

47voto

tsh Punkte 807

Das Exception-Objekt enthält auch die Originalantwort e.response, die nützlich sein könnte, wenn der Fehlerkörper in der Antwort vom Server angezeigt werden muss. Zum Beispiel:

try:
    r = requests.post('somerestapi.com/post-here', data={'birthday': '9/9/3999'})
    r.raise_for_status()
except requests.exceptions.HTTPError as e:
    print (e.response.text)

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X