首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >为什么Python的urllib2.urlopen()会为成功的状态码引发一个HTTPError?

为什么Python的urllib2.urlopen()会为成功的状态码引发一个HTTPError?
EN

Stack Overflow用户
提问于 2011-08-12 05:11:18
回答 3查看 8.2K关注 0票数 17

根据the urllib2 documentation的说法,

因为默认处理程序处理重定向( 300范围内的代码),而100-299范围内的代码表示成功,所以您通常只会看到400-599范围内的错误代码。

然而,下面的代码

代码语言:javascript
复制
request = urllib2.Request(url, data, headers)
response = urllib2.urlopen(request)

引发代码为201的HTTPError (已创建):

代码语言:javascript
复制
ERROR    2011-08-11 20:40:17,318 __init__.py:463] HTTP Error 201: Created

那么,为什么 urllib2 会在这个成功的请求上抛出HTTPErrors呢?

这并不是很麻烦;我可以很容易地将代码扩展为:

代码语言:javascript
复制
try:
    request = urllib2.Request(url, data, headers)
    response = urllib2.urlopen(request)
except HTTPError, e:
    if e.code == 201:
        # success! :)
    else:
        # fail! :(
else:
    # when will this happen...?

但根据文档和我找不到关于这种奇怪行为的类似问题的事实,这似乎不是预期的行为。

还有, else 块应该期待什么?如果成功的状态码都被解释为HTTPError,那么urllib2.urlopen()什么时候会像所有urllib2文档中提到的那样返回一个正常的类似文件的响应对象?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2011-08-12 05:25:55

正如实际的库文档所提到的:

对于200个错误码,立即返回响应对象。

对于非200错误代码,这只是通过OpenerDirector.error()将作业传递给protocol_error_code处理程序方法。最后,如果没有其他处理程序处理错误,urllib2.HTTPDefaultErrorHandler将引发HTTPError。

http://docs.python.org/library/urllib2.html#httperrorprocessor-objects

票数 3
EN

Stack Overflow用户

发布于 2011-08-12 05:26:23

您可以编写与urllib2一起使用的自定义Handler类,以防止将特定错误代码引发为HTTError。下面是我以前用过的一个:

代码语言:javascript
复制
class BetterHTTPErrorProcessor(urllib2.BaseHandler):
    # a substitute/supplement to urllib2.HTTPErrorProcessor
    # that doesn't raise exceptions on status codes 201,204,206
    def http_error_201(self, request, response, code, msg, hdrs):
        return response
    def http_error_204(self, request, response, code, msg, hdrs):
        return response
    def http_error_206(self, request, response, code, msg, hdrs):
        return response

然后你可以像这样使用它:

代码语言:javascript
复制
opener = urllib2.build_opener(self.BetterHTTPErrorProcessor)
urllib2.install_opener(opener)

req = urllib2.Request(url, data, headers)
urllib2.urlopen(req)
票数 16
EN

Stack Overflow用户

发布于 2019-09-02 13:35:36

我个人认为这是一个错误,是非常不直观的,这是默认行为。确实,非2XX代码意味着协议级错误,但将其转变为异常太远了(至少在我看来是这样)。

在任何情况下,我认为避免这种情况的最优雅的方法是:

代码语言:javascript
复制
opener = urllib.request.build_opener()
for processor in opener.process_response['https']: # or http, depending on what you're using
   if isinstance(processor, urllib.request.HTTPErrorProcessor): # HTTPErrorProcessor also for https
       opener.process_response['https'].remove(processor)
       break # there's only one such handler by default
response = opener.open('https://www.google.com')

现在您有了响应对象。你可以检查它的状态码,头,正文等。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7032890

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档