尝试/除了使用Python请求模块的正确方法?

时间:2013-05-12 19:44:44

标签: python request python-requests

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

这是对的吗?有没有更好的方法来构建它?这会涵盖我的所有基础吗?

3 个答案:

答案 0 :(得分:572)

查看请求exception docs。简而言之:

  

如果出现网络问题(例如DNS失败,拒绝连接等),请求将引发 ConnectionError 例外。

     

如果罕见的无效HTTP响应,请求将引发 HTTPError 例外。

     

如果请求超时,则会引发 Timeout 异常。

     

如果请求超出配置的最大重定向数,则会引发 TooManyRedirects 异常。

     

请求明确提出的所有异常都来自 requests.exceptions.RequestException

要回答您的问题,您展示的内容将涵盖您的所有基础。您只能捕获与连接相关的错误,而不是那些超时的错误。

捕获异常时该怎么做才能完全取决于脚本/程序的设计。退出是否可以接受?你能继续再试一次吗?如果错误是灾难性的并且您无法继续,那么是的,对sys.exit()的调用是有序的。

您可以捕获基类异常,它将处理所有情况:

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

或者你可以单独捕捉它们并做不同的事情。

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.
    print e
    sys.exit(1)

正如Christian所指出的那样:

  

如果您希望http错误(例如401 Unauthorized)引发异常,您可以致电Response.raise_for_status。如果响应是http错误,那将引发HTTPError

一个例子:

try:
    r = requests.get('http://www.google.com/nothere')
    r.raise_for_status()
except requests.exceptions.HTTPError as err:
    print err
    sys.exit(1)

将打印:

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

答案 1 :(得分:43)

另外一个明确的建议。最好从特定的错误到一般的错误堆栈,以获得所需的错误,因此特定的错误不会被普通错误掩盖。

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

答案 2 :(得分:2)

异常对象还包含原始响应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)