本文翻译自: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 anHTTPError
, 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)