Comment essayer / sauf utiliser le module de requêtes Python?

Réponses:

797

Jetez un œil aux documents d'exception Requests . En bref:

En cas de problème de réseau (par exemple, panne DNS, connexion refusée, etc.), les demandes déclencheront une ConnectionErrorexception.

En cas de réponse HTTP non valide rare, les demandes lèveront une HTTPErrorexception.

Si une demande expire, une Timeoutexception est déclenchée .

Si une demande dépasse le nombre configuré de redirections maximales, une TooManyRedirectsexception est déclenchée.

Toutes les exceptions que Requests soulève explicitement héritent de requests.exceptions.RequestException.

Pour répondre à votre question, ce que vous montrez ne couvrira pas toutes vos bases. Vous n'attraperez que les erreurs liées à la connexion, pas celles qui expirent.

Que faire lorsque vous interceptez l'exception dépend vraiment de la conception de votre script / programme. Est-il acceptable de quitter? Pouvez-vous continuer et réessayer? Si l'erreur est catastrophique et que vous ne pouvez pas continuer, alors oui, vous pouvez abandonner votre programme en augmentant SystemExit (une bonne façon d'imprimer une erreur et d'appeler sys.exit).

Vous pouvez intercepter l'exception de classe de base, qui gérera tous les cas:

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

Ou vous pouvez les attraper séparément et faire des choses différentes.

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)

Comme l'a souligné Christian :

Si vous souhaitez que les erreurs http (par exemple 401 non autorisé) déclenchent des exceptions, vous pouvez appeler Response.raise_for_status. Cela soulèvera un HTTPError, si la réponse était une erreur http.

Un exemple:

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

Imprime:

404 Client Error: Not Found for url: http://www.google.com/nothere
Jonathon Reinhart
la source
11
Très bonne réponse pour traiter les spécificités de la bibliothèque de requêtes, ainsi que pour les exceptions générales.
Brian Peterson
10
Notez qu'en raison d'un bogue dans la bibliothèque sous-jacente urllib3, vous devrez également intercepter des socket.timeoutexceptions si vous utilisez un délai d'expiration: github.com/kennethreitz/requests/issues/1236
jb.
15
Futurs lecteurs de commentaires: cela a été corrigé dans Requests 2.9 (qui regroupe urllib3 1.13)
RazerM
14
Si vous souhaitez que les erreurs http (par exemple 401 non autorisées) déclenchent des exceptions, vous pouvez appeler Response.raise_for_status . Cela déclenchera une HTTPError, si la réponse était une erreur http.
Christian Long
5
La liste des exceptions sur le site Web de demande n'est pas complète. Vous pouvez lire la liste complète ici .
Epoc
88

Une suggestion supplémentaire pour être explicite. Il semble préférable de passer de spécifique à général dans la pile d'erreurs pour obtenir l'erreur souhaitée, afin que les erreurs spécifiques ne soient pas masquées par l'erreur générale.

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

contre

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
jouell
la source
cette syntaxe est-elle également valable pour la publication?
ScipioAfricanus
@ScipioAfricanus oui.
andrea
10

L'objet d'exception contient également une réponse d'origine e.response, qui pourrait être utile si vous avez besoin de voir le corps de l'erreur en réponse du serveur. Par exemple:

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)
tsh
la source