Python получает заголовки только с помощью urllib2 - PullRequest
1 голос
/ 27 марта 2012

Мне нужно реализовать функцию для получения только заголовков (без выполнения GET или POST) с использованием urllib2.Вот моя функция:

def getheadersonly(url, redirections = True):
    if not redirections:
        class MyHTTPRedirectHandler(urllib2.HTTPRedirectHandler):
            def http_error_302(self, req, fp, code, msg, headers):
                return urllib2.HTTPRedirectHandler.http_error_302(self, req, fp, code, msg, headers)
            http_error_301 = http_error_303 = http_error_307 = http_error_302
        cookieprocessor = urllib2.HTTPCookieProcessor()
        opener = urllib2.build_opener(MyHTTPRedirectHandler, cookieprocessor)
        urllib2.install_opener(opener)

    class HeadRequest(urllib2.Request):
        def get_method(self):
            return "HEAD"

    info = {}
    info['headers'] = dict(urllib2.urlopen(HeadRequest(url)).info()) 
    info['finalurl'] = urllib2.urlopen(HeadRequest(url)).geturl() 
    return info

Использует код из ответа это и это .Однако это делает перенаправление , даже когда флаг False.Я попробовал код с:

print getheadersonly("http://ms.com", redirections = False)['finalurl']
print getheadersonly("http://ms.com")['finalurl']

Это дает morganstanley.com в обоих случаях.Что здесь не так?

Ответы [ 2 ]

7 голосов
/ 27 марта 2012

Во-первых, ваш код содержит несколько ошибок:

  1. При каждом запросе getheadersonly вы устанавливаете новый глобальный urlopener, который затем используется в последующих вызовах urllib2.urlopen

  2. Вы делаете два HTTP-запроса, чтобы получить два разных атрибута ответа.

  3. Реализация urllib2.HTTPRedirectHandler.http_error_302 не так тривиальна, и я непонять, как он может предотвратить перенаправление в первую очередь.

По сути, вы должны понимать, что каждый обработчик установлен в открывателе для обработки определенного типа ответа.urllib2.HTTPRedirectHandler предназначен для преобразования определенных http-кодов в перенаправления.Если вы не хотите перенаправления, не добавляйте обработчик перенаправления в открыватель.Если вы не хотите открывать FTP-ссылки, не добавляйте FTPHandler и т. Д.

Все, что вам нужно, - это создать новый открыватель и добавить в него urllib2.HTTPHandler(), настроить запрос так, чтобыЗапрос "HEAD" и передача экземпляра запроса открывателю, чтение атрибутов и закрытие ответа.

class HeadRequest(urllib2.Request):
    def get_method(self):
        return 'HEAD'

def getheadersonly(url, redirections=True):
    opener = urllib2.OpenerDirector()
    opener.add_handler(urllib2.HTTPHandler())
    opener.add_handler(urllib2.HTTPDefaultErrorHandler())
    if redirections:
        # HTTPErrorProcessor makes HTTPRedirectHandler work
        opener.add_handler(urllib2.HTTPErrorProcessor())
        opener.add_handler(urllib2.HTTPRedirectHandler())
    try:
        res = opener.open(HeadRequest(url))
    except urllib2.HTTPError, res:
        pass
    res.close()
    return dict(code=res.code, headers=res.info(), finalurl=res.geturl())
2 голосов
/ 27 марта 2012

Вы можете отправить запрос HEAD, используя httplib . Запрос HEAD такой же, как запрос GET, но сервер не отправляет тело сообщения.

...