Действительно ли urllib2.urlopen () получает страницу? - PullRequest
2 голосов
/ 09 июня 2010

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

IE действительно ли HTML-страница получает выборку при вызове urlopen иливызов read ()?

handle = urllib2.urlopen(url)
html = handle.read()

Причина, по которой я спрашиваю, заключается в этом рабочем процессе ...

  • У меня есть список URL-адресов (некоторые из них со службами коротких URL-адресов)
  • Я хочу читать веб-страницу, только если я не видел этот URL раньше
  • Мне нужно вызвать urlopen () и использовать geturl (), чтобы получить последнюю страницу, на которую идет ссылка (после302 перенаправляет), поэтому я знаю, просканировал ли я его или нет.
  • Я не хочу нести накладные расходы, связанные с получением HTML, если я уже проанализировал эту страницу.

спасибо!

Ответы [ 6 ]

6 голосов
/ 10 июня 2010

Я только что провел тест с Wireshark. Когда я вызвал urllib2.urlopen («url-for-a-700mbyte-file»), сразу были получены только заголовки и несколько пакетов тела. Только когда я позвонил read (), большая часть тела попала в сеть. Это соответствует тому, что я вижу, читая исходный код модуля httplib.

Итак, чтобы ответить на исходный вопрос, urlopen () не получает все тело по сети. Он извлекает заголовки и обычно некоторые тела. Остальная часть тела извлекается при вызове read ().

Частичное извлечение тела следует ожидать, потому что:

  1. Если вы не читаете HTTP-ответ по одному байту за раз, невозможно точно узнать, какой длины будут входящие заголовки, и, следовательно, невозможно узнать, сколько байтов нужно прочитать до начала тела.

  2. http-клиент не контролирует, сколько байтов сервер объединяет в каждый tcp-кадр ответа.

На практике, поскольку некоторые тела обычно извлекаются вместе с заголовками, вы можете обнаружить, что маленькие тела (например, небольшие HTML-страницы) целиком извлекаются при вызове urlopen ().

3 голосов
/ 09 июня 2010

urllib2 всегда использует HTTP-метод GET (или POST) и, следовательно, неизбежно получает полную страницу. Вместо этого, чтобы использовать HTTP-метод HEAD (который получает только заголовки - которых достаточно для отслеживания перенаправлений!), Я думаю, вам просто нужно создать подкласс urllib2.Request с вашим собственным классом и переопределить один короткий метод:

class MyRequest(urllib2.Request):

    def get_method(self):
        return "HEAD"

и передать соответственно инициализированный экземпляр MyRequest urllib2.urlopen.

1 голос
/ 09 июня 2010

При тестировании на локальном веб-сервере urllib2.urlopen(url) запускает HTTP-запрос, а .read() - нет.

0 голосов
/ 21 марта 2015

Вы можете выбрать чтение части ответа с чем-то вроде ...

urllib2.Request(url, None, requestHeaders).read(CHUNKSIZE)

Это только читает байты CHUNKSIZE с сервера, я только что проверил.

0 голосов
/ 10 июня 2010

С другой стороны, если вы используете Scrapy , он делает HEAD разумно для вас.Нет смысла внедрять собственное решение, когда это уже сделано так хорошо в другом месте .

0 голосов
/ 09 июня 2010

Посмотрев на документы и источник Я почти уверен, что он получает содержимое страницы. Возвращенный объект содержит страницу.

...