Modo corretto di provare / tranne utilizzare il modulo richieste Python?


Risposte:


795

Dai un'occhiata ai documenti di eccezione Richieste . In breve:

In caso di un problema di rete (ad es. Errore DNS, connessione rifiutata, ecc.), Le richieste genereranno ConnectionErrorun'eccezione.

Nel caso della rara risposta HTTP non valida, le richieste genereranno HTTPErrorun'eccezione.

Se una richiesta scade, Timeoutviene sollevata un'eccezione.

Se una richiesta supera il numero configurato di reindirizzamenti massimi, TooManyRedirectsviene sollevata un'eccezione.

Tutte le eccezioni da cui Requests genera esplicitamente l'ereditarietà requests.exceptions.RequestException.

Per rispondere alla tua domanda, ciò che mostri non coprirà tutte le tue basi. Riceverai solo errori relativi alla connessione, non quelli che scadono.

Cosa fare quando si rileva l'eccezione dipende davvero dalla progettazione del proprio script / programma. È accettabile uscire? Puoi continuare e riprovare? Se l'errore è catastrofico e non è possibile continuare, quindi sì, è possibile interrompere il programma sollevando SystemExit (un modo semplice per stampare un errore e chiamaresys.exit ).

Puoi prendere l'eccezione della classe base, che gestirà tutti i casi:

try:
    r = requests.get(url, params={'s': thing})
except requests.exceptions.RequestException as e:  # This is the correct syntax
    raise SystemExit(e)

Oppure puoi prenderli separatamente e fare cose diverse.

try:
    r = requests.get(url, params={'s': thing})
except requests.exceptions.Timeout:
    # Maybe set up for a retry, or continue in a retry loop
except requests.exceptions.TooManyRedirects:
    # Tell the user their URL was bad and try a different one
except requests.exceptions.RequestException as e:
    # catastrophic error. bail.
    raise SystemExit(e)

Come ha sottolineato Christian :

Se si desidera che errori http (ad es. 401 non autorizzati) generino eccezioni, è possibile chiamare Response.raise_for_status. Ciò solleverà un HTTPError, se la risposta fosse un errore http.

Un esempio:

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

Stampa:

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

11
Ottima risposta per la gestione delle specifiche della libreria delle richieste e per la rilevazione generale delle eccezioni.
Brian Peterson,

10
Tieni presente che a causa di un bug nella libreria urllib3 sottostante, dovrai anche catturare le socket.timeouteccezioni se stai usando un timeout: github.com/kennethreitz/requests/issues/1236
jb.

15
Lettori di commenti futuri: questo è stato risolto nelle Richieste 2.9 (che raggruppano urllib3 1.13)
RazerM

14
Se si desidera che errori http (ad es. 401 non autorizzati) generino eccezioni, è possibile chiamare Response.raise_for_status . Ciò genererà un errore HTTP, se la risposta fosse un errore http.
Christian Long,

5
L'elenco delle eccezioni sul sito Web della richiesta non è completo. Puoi leggere l'elenco completo qui .
Epoc

87

Un suggerimento aggiuntivo per essere esplicito. Sembra meglio passare dallo specifico al generale nella pila di errori per ottenere l'errore desiderato, quindi quelli specifici non vengono mascherati da quello generale.

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 Error:",errh)
except requests.exceptions.ConnectionError as errc:
    print ("Error Connecting:",errc)
except requests.exceptions.Timeout as errt:
    print ("Timeout Error:",errt)
except requests.exceptions.RequestException as err:
    print ("OOps: Something Else",err)

Http Error: 404 Client Error: Not Found for 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: Something Else",err)
except requests.exceptions.HTTPError as errh:
    print ("Http Error:",errh)
except requests.exceptions.ConnectionError as errc:
    print ("Error Connecting:",errc)
except requests.exceptions.Timeout as errt:
    print ("Timeout Error:",errt)     

OOps: Something Else 404 Client Error: Not Found for url: http://www.google.com/blahblah

questa sintassi è valida anche per post?
Scipione Africano,

@ScipioAfricanus sì.
andrea,

10

L'oggetto eccezione contiene anche una risposta originale e.response, che potrebbe essere utile se fosse necessario vedere il corpo dell'errore in risposta dal server. Per esempio:

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)
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.