注意:建议使用 response.raise_for_status()
,就像Ian 的回答中所描述的那样(他是requests
模块的维护者之一)。
如何处理这些问题完全取决于您认为 HTTP 错误是什么。虽然有状态码,但除了 200
以外的一切并不一定意味着有某种错误。
正如您所注意到的,请求库将它们视为 HTTP 响应的另一个方面,并且不会引发异常。例如,HTTP 状态码 302
意味着“找到了”,但响应没有包含响应正文,而是包含一个 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)
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:
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 中已改变为执行浮点数除法)。 因此,对于所有 2xx
状态码,status // 100 == 2
都成立。
request
库将它们视为HTTP响应的另一个方面,并不会引发异常。因此,对于你的用例,你需要更具体地说明什么构成了“错误”。 - Lukas Graf