Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ember.js/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么Python';s urllib2.urlopen()是否为成功的状态代码引发HTTPError?_Python_Urllib2_Http Status Codes - Fatal编程技术网

为什么Python';s urllib2.urlopen()是否为成功的状态代码引发HTTPError?

为什么Python';s urllib2.urlopen()是否为成功的状态代码引发HTTPError?,python,urllib2,http-status-codes,Python,Urllib2,Http Status Codes,根据, 因为默认处理程序处理重定向(300范围内的代码),而100-299范围内的代码表示成功,所以通常只会看到400-599范围内的错误代码 但是下面的代码 request = urllib2.Request(url, data, headers) response = urllib2.urlopen(request) 引发代码为201的HTTPError(已创建): 那么为什么urllib2在这个成功的请求上抛出HTTPErrors呢? 这不是太痛苦;我可以轻松地将代码扩展到: try:

根据,

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

但是下面的代码

request = urllib2.Request(url, data, headers)
response = urllib2.urlopen(request)
引发代码为201的HTTPError(已创建):

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

这不是太痛苦;我可以轻松地将代码扩展到:

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...?
但这似乎不是预期的行为,基于文档和事实,我找不到关于这种奇怪行为的类似问题


另外,如果成功的状态代码都被解释为
HTTPError
s,那么
urllib2.urlopen()什么时候执行
只需返回一个普通的类似文件的响应对象,就像所有的
urllib2
文档所引用的一样?

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

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

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


您可以编写一个自定义的
处理程序
类,与
urllib2
一起使用,以防止特定的错误代码作为
HTTError
引发。这是我以前用过的一个:

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
然后你可以像这样使用它:

opener = urllib2.build_opener(self.BetterHTTPErrorProcessor)
urllib2.install_opener(opener)

req = urllib2.Request(url, data, headers)
urllib2.urlopen(req)

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

无论如何,我认为最优雅的避免方法是:

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')

现在您有了响应对象。您可以检查它的状态代码、标题、正文等。

在201-299之间看到响应代码是非常罕见的。毫不奇怪urllib2没有完美地处理它们。我是否遗漏了什么?201对我来说很好…@Santa,根据dcrosta的回答,也许你使用的是非标准处理器?@Leopd:事实上是这样。查看Python27\Lib中的当前urllib2.py源代码,第511-3行。当
try
块成功执行时,将执行最后的
else
语句-您可以将其读取为
if exception:else:
如果有帮助。
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')