requests - ¿Cómo se envía una solicitud HEAD HTTP en Python 2?
post en python (11)
Como comentario aparte, al usar el httplib (al menos en 2.5.2), al intentar leer la respuesta de una solicitud HEAD se bloqueará (en readline) y posteriormente fallará. Si no emite leer en la respuesta, no puede enviar otra solicitud en la conexión, deberá abrir una nueva. O acepte una larga demora entre las solicitudes.
Lo que trato 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, necesito averiguar cómo enviar una solicitud HEAD para que pueda leer el tipo MIME sin tener que descargar el contenido. ¿Alguien sabe de una manera fácil de hacer esto?
Creo que la biblioteca de requests debería mencionarse.
He descubierto que httplib es ligeramente más rápido que urllib2. Temporicé dos programas, 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: usuario real 6m21.334s 0m2.124s sys 0m16.372s
Y las estadísticas totales de urllib2 fueron: usuario real de 9m1.380s 0m16.666s sys 0m28.565s
¿Alguien más tiene información sobre esto?
Obligatory Requests
way:
import requests
resp = requests.head("http://www.google.com")
print resp.status_code, resp.text, resp.headers
Para completar, tener una respuesta de Python3 equivalente a la respuesta aceptada usando httplib .
Básicamente es el mismo código simplemente 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)
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 () [''content-type''], etc.
http://docs.python.org/library/urllib.html
http://docs.python.org/library/urllib2.html
http://docs.python.org/library/httplib.html
Los documentos indican que httplib normalmente no se usa directamente.
Sólo:
import urllib2
request = urllib2.Request(''http://localhost:8080'')
request.get_method = lambda : ''HEAD''
response = urllib2.urlopen(request)
response.info().gettype()
Editar: 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''
...
Y otro enfoque más (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.
urllib2 se puede usar para realizar una solicitud HEAD. Esto es un poco mejor que usar httplib ya que urllib2 analiza la URL por usted en lugar de requerir que divida la URL en el nombre de host y la 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, puedes encontrar la URL a la que fuiste redirigido:
>>> print response.geturl()
http://www.google.com.au/index.html
editar : esta respuesta funciona, pero hoy en día solo debes usar la biblioteca de requests como se menciona en otras respuestas a continuación.
Use 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.
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