Примечание. Лучше использовать response.raise_for_status()
, как описано в ответе Яна выше (он один из сопровождающих модуля requests
).
То, как вы справляетесь со всем этим, зависит от того, что вы считаете ошибкой HTTP. Есть коды состояния, но не все, кроме 200
, обязательно означает наличие какой-то ошибки.
Как вы заметили, библиотека запросов рассматривает их как еще один аспект HTTP-ответа и не вызывает исключения. Статус HTTP 302
, например, означает Found
, но ответ содержит не тело ответа, а заголовок Location
, которому вам нужно следовать, чтобы добраться до нужного вам ресурса.
Итак, вам следует взглянуть на response.status_code
и обработайте это, отловив фактические ошибки протокола с помощью try..except
. При их перехвате вы должны фактически перехватывать requests.exceptions.RequestException
, потому что это базовый класс для всех другие исключения, которые вызывает модуль requests
.
Итак, вот пример, демонстрирующий все три случая:
- Успешный
200 OK
ответ
- Успешный запрос и ответ, но статус отличается от
200
- Ошибка протокола (неверная схема)
import requests
test_urls = ['http://httpbin.org/user-agent',
'http://httpbin.org/status/404',
'http://httpbin.org/status/500',
'httpx://invalid/url']
def return_json(url):
try:
response = requests.get(url)
# Consider any status other than 2xx an error
if not response.status_code // 100 == 2:
return "Error: Unexpected response {}".format(response)
json_obj = response.json()
return json_obj
except requests.exceptions.RequestException as e:
# A serious problem happened, like an SSLError or InvalidURL
return "Error: {}".format(e)
for url in test_urls:
print "Fetching URL '{}'".format(url)
print return_json(url)
print
Выход:
Fetching URL 'http://httpbin.org/user-agent'
{u'user-agent': u'python-requests/2.1.0 CPython/2.7.1 Darwin/11.4.2'}
Fetching URL 'http://httpbin.org/status/404'
Error: Unexpected response <Response [404]>
Fetching URL 'http://httpbin.org/status/500'
Error: Unexpected response <Response [500]>
Fetching URL 'httpx://invalid/url'
Error: No connection adapters were found for 'httpx://invalid/url'
Также может быть исключение, вызванное response.json()
, если вы получите успешный ответ, но это просто не JSON, поэтому вы также можете учитывать это.
Примечание. Бит if not response.status_code // 100 == 2
работает следующим образом: оператор //
выполняет так называемую полное деление, поэтому оно округляется до следующего целого числа (это поведение по умолчанию для /
в Python 2.x, но не в Python 3.x, где /
было изменено для работы с плавающей запятой). разделение). Таким образом, status // 100 == 2
верно для всех кодов 2xx
.
person
Lukas Graf
schedule
01.07.2014
200
, обязательно означает наличие какой-то ошибки. Как вы заметили, библиотекаrequest
рассматривает их как еще один аспект HTTP-ответа и не вызывает исключения. Поэтому вам нужно быть немного более конкретным в отношении того, что представляет собой ошибку для вашего варианта использования. - person Lukas Graf   schedule 02.07.2014