尝试/排除使用 Python requests 模块的正确方法?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16511337/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-18 22:51:57  来源:igfitidea点击:

Correct way to try/except using Python requests module?

pythonrequestpython-requests

提问by John Smith

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?

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

采纳答案by Jonathon Reinhart

Have a look at the Requests exception docs. In short:

查看请求异常文档。简而言之:

In the event of a network problem (e.g. DNS failure, refused connection, etc), Requests will raise a ConnectionErrorexception.

In the event of the rare invalid HTTP response, Requests will raise an HTTPErrorexception.

If a request times out, a Timeoutexception is raised.

If a request exceeds the configured number of maximum redirections, a TooManyRedirectsexception is raised.

All exceptions that Requests explicitly raises inherit from requests.exceptions.RequestException.

如果出现网络问题(例如 DNS 故障、拒绝连接等),Requests 将引发ConnectionError异常。

如果出现罕见的无效 HTTP 响应,Requests 将引发HTTPError异常。

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

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

Requests 显式引发的所有异常都继承自requests.exceptions.RequestException.

To answer your question, what you show will notcover 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, you may abort your program by raising SystemExit(a nice way to both print an error and call sys.exit).

当您捕获异常时该怎么做实际上取决于您的脚本/程序的设计。退出是否可以接受?你能继续再试一次吗?如果错误是灾难性的并且您无法继续,那么是的,您可以通过引发SystemExit来中止程序(打印错误和调用的好方法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
    raise SystemExit(e)

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.
    raise SystemExit(e)


As Christianpointed out:

正如克里斯蒂安指出的那样:

If you want http errors (e.g. 401 Unauthorized) to raise exceptions, you can call Response.raise_for_status. That will raise an HTTPError, if the response was an http error.

如果您希望 http 错误(例如 401 Unauthorized)引发异常,您可以调用Response.raise_for_status. HTTPError如果响应是 http 错误,则会引发, 。

An example:

一个例子:

try:
    r = requests.get('http://www.google.com/nothere')
    r.raise_for_status()
except requests.exceptions.HTTPError as err:
    raise SystemExit(err)

Will print:

将打印:

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

回答by jouell

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

回答by tsh

Exception object also contains original response e.response, that could be useful if need to see error body in response from the server. For example:

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