Как отправить HTTP-запрос HEAD в Python 2?

Здесь я пытаюсь получить заголовки заданного URL-адреса, чтобы я мог определить тип MIME. Я хочу увидеть, вернет ли http://somedomain/foo/ документ HTML или изображение JPEG, например. Таким образом, мне нужно выяснить, как отправить запрос HEAD, чтобы я мог читать тип MIME без необходимости загружать контент. Кто-нибудь знает простой способ сделать это?


person fuentesjr    schedule 20.09.2008    source источник


Ответы (11)


изменить: этот ответ работает, но в настоящее время вы должны просто использовать запрашивает библиотеку, как указано в других ответах ниже.


Используйте https://docs.python.org/2/library/httplib.html.

>>> import httplib
>>> conn = httplib.HTTPConnection("www.google.com")
>>> conn.request("HEAD", "/index.html")
>>> res = conn.getresponse()
>>> print res.status, res.reason
200 OK
>>> print res.getheaders()
[('content-length', '0'), ('expires', '-1'), ('server', 'gws'), ('cache-control', 'private, max-age=0'), ('date', 'Sat, 20 Sep 2008 06:43:36 GMT'), ('content-type', 'text/html; charset=ISO-8859-1')]

Также есть getheader(name) для получения определенного заголовка.

person Eevee    schedule 20.09.2008
comment
этот ответ помечен как отвеченный, но нужно посмотреть файл requests lib. Посмотрите на ответ Далиуса, который находится чуть ниже. - person Bahadir Cambel; 23.12.2011
comment
Это действительно хорошо, но требует, чтобы у вас были отдельные значения для хоста и пути запроса. Полезно иметь под рукой urlparse, о чем свидетельствует ответ более низкого ранга. - person Tomasz Gandor; 10.01.2013
comment
Примечание для Python 3; httplib переименован в http.client. - person Santosh Kumar; 13.03.2013
comment
К сожалению, requests по умолчанию не поставляется с Python. - person rook; 18.11.2013
comment
@rook тоже не твоя программа :) - person Eevee; 18.11.2013

urllib2 можно использовать для выполнения запроса HEAD. Это немного лучше, чем использование httplib, поскольку urllib2 анализирует URL-адрес для вас, вместо того, чтобы требовать, чтобы вы разбили URL-адрес на имя хоста и путь.

>>> import urllib2
>>> class HeadRequest(urllib2.Request):
...     def get_method(self):
...         return "HEAD"
... 
>>> response = urllib2.urlopen(HeadRequest("http://google.com/index.html"))

Заголовки, как и раньше, доступны через response.info (). Интересно, что вы можете найти URL-адрес, на который вы были перенаправлены:

>>> print response.geturl()
http://www.google.com.au/index.html
person doshea    schedule 15.01.2010
comment
response.info () .__ str __ () вернет строковый формат заголовка, если вы хотите что-то сделать с полученным результатом. - person Shane; 12.10.2010
comment
за исключением того, что пытаясь это сделать с помощью python 2.7.1 (ubuntu natty), если есть перенаправление, он выполняет GET в пункте назначения, а не в HEAD ... - person eichin; 23.08.2011
comment
В этом преимущество httplib.HTTPConnection, который не обрабатывает перенаправления автоматически. - person Ehtesh Choudhury; 04.10.2011
comment
но с ответом доши. как установить тайм-аут? Как обрабатывать неверные URL-адреса, то есть URL-адреса, которых больше нет. - person fanchyna; 19.08.2013

Обязательный Requests способ:

import requests

resp = requests.head("http://www.google.com")
print resp.status_code, resp.text, resp.headers
person K Z    schedule 21.10.2012

Я считаю, что также следует упомянуть библиотеку Requests.

person daliusd    schedule 12.09.2011
comment
Этот ответ заслуживает большего внимания. Похоже на неплохую библиотеку, которая упрощает задачу. - person Nick Retallack; 27.10.2011
comment
Я согласен. Делать запросы было очень просто: {code} запросы на импорт r = requests.head ('github.com') {code} - person Luis R.; 17.11.2011
comment
@LuisR .: если есть перенаправление, то оно также следует за GET / POST / PUT / DELETE. - person jfs; 10.02.2012
comment
@Nick Retallack: нет простого способа отключить перенаправления. allow_redirects может отключать только перенаправления POST / PUT / DELETE. Пример: запрос заголовка без перенаправления - person jfs; 10.02.2012
comment
@ J.F.Sebastian Ссылка на ваш пример, похоже, не работает. Не могли бы вы подробнее рассказать о проблеме со следующими переадресациями? - person Piotr Dobrogost; 30.08.2012
comment
@Piotr: Проблема заключалась в том, что requests.head(URL) не остановился на перенаправлении и сделал дополнительные запросы GET. Текущая версия 0.13.9 больше этого не делает (по крайней мере, для 301, 302 редиректов). - person jfs; 31.08.2012
comment
@ J.F.Sebastian Похоже, это было исправлено в ревизии 6f57352 - person Piotr Dobrogost; 31.08.2012
comment
@Piotr: изменилось еще кое-что. Как я сказал выше, allow_redirects работал за счет включения перенаправления для POST, т.е. allow_redirects не влиял на HEAD. - person jfs; 31.08.2012
comment
проверьте это: stackoverflow .com / questions / 2018026 / для сравнения различных библиотек, которые могут быть использованы для этого. Запросы кажутся самыми популярными. - person brita_; 29.04.2014

Просто:

import urllib2
request = urllib2.Request('http://localhost:8080')
request.get_method = lambda : 'HEAD'

response = urllib2.urlopen(request)
response.info().gettype()

Изменить: я только что понял, что есть httplib2: D

import httplib2
h = httplib2.Http()
resp = h.request("http://www.google.com", 'HEAD')
assert resp[0]['status'] == 200
assert resp[0]['content-type'] == 'text/html'
...

текст ссылки

person Paweł Prażak    schedule 12.12.2010
comment
Немного неприятно, потому что вы оставляете get_method как несвязанную функцию, а не привязываете ее к request. (То есть, это будет работать, но это плохой стиль, и если вы хотите использовать в нем self - сложно.) - person Chris Morgan; 12.12.2010
comment
Не могли бы вы подробнее рассказать о плюсах и минусах этого решения? Я не эксперт по Python, как вы можете видеть, поэтому мне было бы полезно знать, когда он может стать плохим;) Насколько я понимаю, проблема заключается в том, что это хак, который может или не может сработать в зависимости от изменения реализации? - person Paweł Prażak; 12.12.2010
comment
Эта вторая версия в этом коде - единственная, которая работала для меня для URL с 403 Forbidden. Другие бросали исключение. - person duality_; 11.04.2013

Для полноты, чтобы получить ответ Python3, эквивалентный принятому ответу с использованием httplib.

По сути, это тот же код, только библиотека больше не называется httplib, а называется http.client

from http.client import HTTPConnection

conn = HTTPConnection('www.google.com')
conn.request('HEAD', '/index.html')
res = conn.getresponse()

print(res.status, res.reason)
person Octavian A. Damiean    schedule 14.03.2013

Кстати, при использовании httplib (по крайней мере, в 2.5.2) попытка прочитать ответ на запрос HEAD будет блокироваться (в строке чтения) и впоследствии завершаться ошибкой. Если вы не выдадите read в ответе, вы не сможете отправить еще один запрос на соединение, вам нужно будет открыть новый. Или согласитесь с большой задержкой между запросами.

person Community    schedule 23.04.2009

Я обнаружил, что httplib немного быстрее urllib2. Я рассчитал время для двух программ - одна с использованием httplib, а другая с использованием urllib2 - отправка запросов HEAD на 10 000 URL-адресов. Httplib был быстрее на несколько минут. Общая статистика httplib: реальные 6m21.334s пользователь 0m2.124s sys 0m16.372s.

И общая статистика urllib2 была: реальные 9m1.380s пользователь 0m16.666s sys 0m28.565s.

Кто-нибудь еще имеет мнение по этому поводу?

person IgorGanapolsky    schedule 13.04.2010
comment
Вход? Проблема связана с вводом-выводом, и вы используете блокирующие библиотеки. Переключитесь на eventlet или twisted, если вам нужна лучшая производительность. Упомянутые вами ограничения urllib2 зависят от ЦП. - person Devin Jeanpierre; 13.08.2010
comment
urllib2 следует перенаправлениям, поэтому, если некоторые из ваших URL-адресов перенаправляют, это, вероятно, будет причиной разницы. И httplib является более низкоуровневым, urllib2, например, анализирует URL-адрес. - person Marian; 26.08.2010
comment
urllib2 - это всего лишь тонкий слой абстракции поверх httplib, я был бы очень удивлен, если бы вы были привязаны к процессору, если URL-адреса не находятся в очень быстрой локальной сети. Возможно ли, что некоторые URL-адреса были переадресациями? urllib2 будет следовать перенаправлениям, а httplib - нет. Другая возможность состоит в том, что условия сети (то, что вы не имеете явного контроля в этом эксперименте) колебались между двумя запусками. вы должны сделать как минимум 3 чередующихся прогона каждого, чтобы уменьшить эту вероятность - person John La Rooy; 20.02.2011

И еще один подход (похожий на ответ Павла):

import urllib2
import types

request = urllib2.Request('http://localhost:8080')
request.get_method = types.MethodType(lambda self: 'HEAD', request, request.__class__)

Просто чтобы избежать неограниченных методов на уровне экземпляра.

person estani    schedule 06.06.2013

Наверное, проще: используйте urllib или urllib2.

>>> import urllib
>>> f = urllib.urlopen('http://google.com')
>>> f.info().gettype()
'text/html'

f.info () - объект, подобный словарю, поэтому вы можете использовать f.info () ['content-type'] и т. д.

http://docs.python.org/library/urllib.html
http://docs.python.org/library/urllib2.html
http://docs.python.org/library/httplib.html

В документации отмечается, что httplib обычно не используется напрямую.

person Community    schedule 11.12.2008
comment
Однако urllib выполнит GET, и вопрос будет в выполнении HEAD. Может быть, плакат не хочет получать дорогой документ. - person Philippe F; 06.05.2009

person    schedule
comment
Какие знаки доллара перед import? +1 за urlparse - вместе с httplib они дают комфорт urllib2 при работе с URL-адресами на стороне ввода. - person Tomasz Gandor; 10.01.2013