¿Cómo se envía una solicitud HEAD HTTP en Python 2?

Lo que estoy tratando de hacer aquí es obtener los encabezados de una URL determinada para poder determinar el tipo MIME. Quiero poder ver si http://somedomain/foo/ devolverá un documento HTML o una imagen JPEG, por ejemplo. Por lo tanto, debo averiguar cómo enviar una solicitud HEAD para poder leer el tipo MIME sin tener que descargar el contenido. ¿Alguien sabe de una manera fácil de hacer esto?

edición : esta respuesta funciona, pero en la actualidad solo debe usar la biblioteca de solicitudes como se menciona en otras respuestas a continuación.


Utilice httplib .

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

También hay un getheader(name) para obtener un encabezado específico.

urllib2 se puede utilizar para realizar una solicitud HEAD. Esto es un poco mejor que usar httplib ya que urllib2 analiza la URL en lugar de requerirle que divida la URL en nombre de host y ruta.

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

Los encabezados están disponibles a través de response.info () como antes. Curiosamente, puede encontrar la URL a la que fue redirigido a:

 >>> print response.geturl() http://www.google.com.au/index.html 

Requests obligatorias de manera:

 import requests resp = requests.head("http://www.google.com") print resp.status_code, resp.text, resp.headers 

Creo que la biblioteca de solicitudes debe mencionarse también.

Sólo:

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

Edit: Me acabo de dar cuenta de que hay 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' ... 

Texto del enlace

Para que esté completo, tenga una respuesta de Python3 equivalente a la respuesta aceptada utilizando httplib .

Básicamente es el mismo código solo que la biblioteca ya no se llama httplib sino 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) 
 import httplib import urlparse def unshorten_url(url): parsed = urlparse.urlparse(url) h = httplib.HTTPConnection(parsed.netloc) h.request('HEAD', parsed.path) response = h.getresponse() if response.status/100 == 3 and response.getheader('Location'): return response.getheader('Location') else: return url 

Como punto de partida, al usar el httplib (al menos en 2.5.2), intentar leer la respuesta de una solicitud HEAD se bloqueará (en la línea de lectura) y luego fallará. Si no emite una lectura en la respuesta, no puede enviar otra solicitud por la conexión, deberá abrir una nueva. O aceptar un largo retraso entre las solicitudes.

He encontrado que httplib es un poco más rápido que urllib2. Programé dos progtwigs, uno usando httplib y el otro usando urllib2, enviando solicitudes HEAD a 10,000 URL. El httplib fue más rápido por varios minutos. Las estadísticas totales de httplib fueron: real 6m21.334s usuario 0m2.124s sys 0m16.372s

Y las estadísticas totales de urllib2 fueron: usuario real 9m1.380s 0m16.666s sys 0m28.565s

¿Alguien más tiene entrada en esto?

Y aún otro enfoque (similar a la respuesta de Pawel):

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

Solo para evitar tener métodos ilimitados a nivel de instancia.

Probablemente más fácil: use urllib o urllib2.

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

f.info () es un objeto similar a un diccionario, por lo que puede hacer f.info () [‘tipo de contenido’], etc.

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

La documentación señala que httplib no se usa normalmente directamente.