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

本文翻译自:Correct way to try/except using Python requests module?

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

Is this correct? 这个对吗? Is there a better way to structure this? 有没有更好的方法来构造它? Will this cover all my bases? 这会覆盖我所有的基地吗?


#1楼

参考:https://stackoom.com/question/17HLt/尝试-使用Python请求模块的正确方法


#2楼

Have a look at the Requests exception docs . 看一下Requests 异常文档 In short: 简而言之:

In the event of a network problem (eg DNS failure, refused connection, etc), Requests will raise a ConnectionError exception. 如果出现网络问题(例如DNS故障,拒绝连接等),请求将引发ConnectionError异常。

In the event of the rare invalid HTTP response, Requests will raise an HTTPError exception. 如果发生罕见的无效HTTP响应,则请求将引发HTTPError异常。

If a request times out, a Timeout exception is raised. 如果请求Timeout则会引发“ Timeout异常。

If a request exceeds the configured number of maximum redirections, a TooManyRedirects exception is raised. 如果请求超过配置的最大重定向数,则会引发TooManyRedirects异常。

All exceptions that Requests explicitly raises inherit from requests.exceptions.RequestException . Requests显式引发的所有异常都继承自requests.exceptions.RequestException

To answer your question, what you show will not cover all of your bases. 要回答您的问题,您显示的内容不会涵盖所有基础。 You'll only catch connection-related errors, not ones that time out. 您将只捕获与连接有关的错误,而不是超时的错误。

What to do when you catch the exception is really up to the design of your script/program. 捕获异常时该做什么实际上取决于脚本/程序的设计。 Is it acceptable to exit? 可以退出吗? Can you go on and try again? 您可以再试一次吗? If the error is catastrophic and you can't go on, then yes, a call to sys.exit() is in order. 如果错误是灾难性的,并且您无法继续操作,那么可以,对sys.exit()的调用是sys.exit()

You can either catch the base-class exception, which will handle all cases: 您可以捕获基类异常,该异常将处理所有情况:

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

Or you can catch them separately and do different things. 或者,您可以分别捕获它们并执行不同的操作。

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)

As Christian pointed out: 正如克里斯蒂安指出:

If you want http errors (eg 401 Unauthorized) to raise exceptions, you can call Response.raise_for_status . 如果您希望http错误(例如401未经授权)引发异常,则可以调用Response.raise_for_status That will raise an HTTPError , if the response was an http error. 如果响应是http错误,则将引发HTTPError

An example: 一个例子:

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

Will print: 将打印:

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

#3楼

One additional suggestion to be explicit. 另一项建议是明确的。 It seems best to go from specific to general down the stack of errors to get the desired error to be caught, so the specific ones don't get masked by the general one. 似乎最好是从特定错误到一般错误,以获取所需的错误来捕获,因此特定错误不会被一般错误掩盖。

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

#4楼

Exception object also contains original response e.response , that could be useful if need to see error body in response from the server. 异常对象还包含原始响应e.response ,如果需要查看服务器响应中的错误正文,该对象可能很有用。 For example: 例如:

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)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值