Почему Python urllib2.urlopen () вызывает HTTPError для успешных кодов состояния? - PullRequest
17 голосов
/ 12 августа 2011

Согласно документации urllib2 ,

Поскольку обработчики по умолчанию обрабатывают перенаправления (коды в диапазоне 300), а коды в диапазоне 100-299 указывают на успех, выобычно будут видеть только коды ошибок в диапазоне 400-599.

И все же следующий код

request = urllib2.Request(url, data, headers)
response = urllib2.urlopen(request)

вызывает HTTPError с кодом 201 (создано):

ERROR    2011-08-11 20:40:17,318 __init__.py:463] HTTP Error 201: Created

Так почему 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...?

Но это не похоже на предполагаемое поведение, основанное на документации и том факте, что я не могу найти похожие вопросы об этом странном поведении.

Кроме того, чего ожидать блоку else? Если все успешные коды состояния интерпретируются как HTTPError с, то когда urllib2.urlopen() просто возвращает обычный файл-подобныйобъект ответа, как и вся документация urllib2, на которую ссылается?

Ответы [ 2 ]

16 голосов
/ 12 августа 2011

Вы можете написать собственный класс Handler для использования с 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)
3 голосов
/ 12 августа 2011

Как указывается в фактической документации библиотеки:

Для 200 кодов ошибок объект ответа возвращается немедленно.

Для кодов ошибок, отличных от 200, это просто передает задание в методы-обработчики protocol_error_code через OpenerDirector.error (). В конце концов, urllib2.HTTPDefaultErrorHandler вызовет HTTPError, если никакой другой обработчик не обработает ошибку.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...