Правильный способ попробовать / кроме использования модуля запросов Python?


419
try:
    r = requests.get(url, params={'s': thing})
except requests.ConnectionError, e:
    print e #should I also sys.exit(1) after this?

Это правильно? Есть ли лучший способ структурировать это? Будет ли это охватывать все мои базы?


Ответы:


797

Взгляните на документацию по исключениям Requests . Короче говоря:

В случае проблем с сетью (например, сбой DNS, отказ в соединении и т. Д.), Запросы будут вызывать ConnectionErrorисключение.

В случае редкого неверного HTTP-ответа запросы будут вызывать HTTPErrorисключение.

Если время ожидания истекло, возникает Timeoutисключение.

Если запрос превышает настроенное количество максимальных перенаправлений, возникает TooManyRedirectsисключение.

Все исключения, которые явно вызывает Requests, наследуются от requests.exceptions.RequestException.

Чтобы ответить на ваш вопрос, то, что вы показываете, не будет охватывать все ваши базы. Вы будете ловить только ошибки, связанные с подключением, а не те, которые истекли.

Что делать, когда вы ловите исключение, действительно зависит от дизайна вашего скрипта / программы. Это приемлемо для выхода? Можете ли вы продолжить и попробовать еще раз? Если ошибка катастрофическая и вы не можете продолжить, тогда да, вы можете прервать свою программу, вызвав SystemExit (хороший способ как распечатать ошибку, так и вызвать sys.exit).

Вы можете перехватить исключение базового класса, которое будет обрабатывать все случаи:

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

Или вы можете поймать их отдельно и делать разные вещи.

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)

Как указал Кристиан :

Если вы хотите, чтобы ошибки http (например, 401 Unauthorized) вызывали исключения, вы можете позвонить Response.raise_for_status. Это вызовет HTTPErrorответ, если в ответе была ошибка http.

Пример:

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

Распечатает:

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

11
Очень хороший ответ для работы со спецификой библиотеки запросов, а также для общего поиска исключений.
Брайан Петерсон

10
Обратите внимание, что из-за ошибки в лежащей в основе библиотеке urllib3 вам также нужно будет перехватывать socket.timeoutисключения, если вы используете тайм-аут: github.com/kennethreitz/requests/issues/1236
jb.

15
Будущие читатели комментариев: это было исправлено в Запросах 2.9 (который включает urllib3 1.13)
RazerM

14
Если вы хотите, чтобы ошибки http (например, 401 Unauthorized) вызывали исключения, вы можете вызвать Response.raise_for_status . Это вызовет HTTPError, если ответом была ошибка http.
Кристиан Лонг

5
Список исключений на веб-сайте запроса не является полным. Вы можете прочитать полный список здесь .
Epoc

88

Еще одно предложение должно быть явным. Кажется, лучше всего перейти от конкретного к общему списку ошибок, чтобы получить желаемую ошибку, которая будет перехвачена, поэтому конкретные не будут маскироваться общим.

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

против

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

это правильный синтаксис для поста тоже?
ScipioAfricanus

@ScipioAfricanus да.
Andrea

10

Объект исключения также содержит оригинальный ответ e.response, который может быть полезен, если необходимо увидеть тело ошибки в ответе от сервера. Например:

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)
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.