headers has from attribute python urllib forwarding

has - urllib python install



Python: ¿Obtener encabezados HTTP desde la llamada a urllib2.urlopen? (6)

¿ urllib2 recupera toda la página cuando se realiza una llamada urlopen ?

Me gustaría simplemente leer el encabezado de respuesta HTTP sin obtener la página. Parece que urllib2 abre la conexión HTTP y luego obtiene la página HTML real ... ¿o simplemente comienza a almacenar en búfer la página con la llamada urlopen ?

import urllib2 myurl = ''http://www.kidsidebyside.org/2009/05/come-and-draw-the-circle-of-unity-with-us/'' page = urllib2.urlopen(myurl) // open connection, get headers html = page.readlines() // stream page


¿Qué hay de enviar una solicitud HEAD en lugar de una solicitud GET normal? El siguiente recorte (copiado de una pregunta similar) hace exactamente eso.

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


En realidad, parece que urllib2 puede hacer una solicitud HTTP HEAD.

La pregunta a la que se vincula @reto, arriba, muestra cómo hacer que urllib2 haga una solicitud HEAD.

Aquí está mi opinión sobre esto:

import urllib2 # Derive from Request class and override get_method to allow a HEAD request. class HeadRequest(urllib2.Request): def get_method(self): return "HEAD" myurl = ''http://bit.ly/doFeT'' request = HeadRequest(myurl) try: response = urllib2.urlopen(request) response_headers = response.info() # This will just display all the dictionary key-value pairs. Replace this # line with something useful. response_headers.dict except urllib2.HTTPError, e: # Prints the HTTP Status code of the response but only if there was a # problem. print ("Error code: %s" % e.code)

Si comprueba esto con algo como el analazer de protocolo de red Wireshark, puede ver que en realidad está enviando una solicitud HEAD, en lugar de un GET.

Esta es la solicitud y respuesta HTTP del código anterior, según lo capturado por Wireshark:

HEAD / doFeT HTTP / 1.1
Aceptar-Codificar: identidad
Anfitrión: bit.ly
Conexión: cerrar
User-Agent: Python-urllib / 2.7

HTTP / 1.1 301 movido
Servidor: nginx
Fecha: dom 19 de febrero de 2012 13:20:56 GMT
Content-Type: text / html; charset = utf-8
Cache-control: privado; max-age = 90
Ubicación: http://www.kidsidebyside.org/?p=445
Versión MIME: 1.0
Longitud del contenido: 127
Conexión: cerrar
Set-Cookie: _bit = 4f40f738-00153-02ed0-421cf10a; domain = .bit.ly; expira = viernes 17 de agosto a las 13:20:56 2012; path = /; HttpOnly

Sin embargo, como se menciona en uno de los comentarios en la otra pregunta, si la URL en cuestión incluye una redirección, entonces urllib2 hará una solicitud GET al destino, no a HEAD. Esto podría ser una deficiencia importante, si realmente quisiera hacer solo solicitudes HEAD.

La solicitud anterior implica una redirección. Aquí está la solicitud al destino, según lo capturado por Wireshark:

GET / 2009/05 / come-and-draw-the-circle-of-unity-with-us / HTTP / 1.1
Aceptar-Codificar: identidad
Anfitrión: www.kidsidebyside.org
Conexión: cerrar
User-Agent: Python-urllib / 2.7

Una alternativa al uso de urllib2 es usar la biblioteca httplib2 de Joe Gregorio:

import httplib2 url = "http://bit.ly/doFeT" http_interface = httplib2.Http() try: response, content = http_interface.request(url, method="HEAD") print ("Response status: %d - %s" % (response.status, response.reason)) # This will just display all the dictionary key-value pairs. Replace this # line with something useful. response.__dict__ except httplib2.ServerNotFoundError, e: print (e.message)

Esto tiene la ventaja de utilizar solicitudes HEAD tanto para la solicitud HTTP inicial como para la solicitud redirigida a la URL de destino.

Aquí está la primera solicitud:

HEAD / doFeT HTTP / 1.1
Anfitrión: bit.ly
aceptar-codificación: gzip, desinflar
usuario-agente: Python-httplib2 / 0.7.2 (gzip)

Aquí está la segunda solicitud, al destino:

HEAD / 2009/05 / come-and-draw-the-circle-of-unity-with-us / HTTP / 1.1
Anfitrión: www.kidsidebyside.org
aceptar-codificación: gzip, desinflar
usuario-agente: Python-httplib2 / 0.7.2 (gzip)


Un trazador de líneas:

$ python -c "import urllib2; print urllib2.build_opener(urllib2.HTTPHandler(debuglevel=1)).open(urllib2.Request(''http://google.com''))"


Use el método response.info() para obtener los encabezados.

De los documentos urllib2 :

urllib2.urlopen (url [, data] [, timeout])

...

Esta función devuelve un objeto similar a un archivo con dos métodos adicionales:

  • geturl () - devuelve la URL del recurso recuperado, comúnmente utilizado para determinar si se siguió un redireccionamiento
  • info () - devuelve la metainformación de la página, como encabezados, en forma de una instancia de httplib.HTTPMessage (ver Referencia rápida a encabezados HTTP)

Por lo tanto, para su ejemplo, intente recorrer el resultado de los response.info().headers de response.info().headers para lo que está buscando.

Tenga en cuenta que la principal advertencia al uso de httplib.HTTPMessage está documentada en el problema 4773 de Python .


urllib2.urlopen hace un HTTP GET (o POST si proporciona un argumento de datos), no un HEAD HTTP (si hiciera esto último, no podría hacer readlines u otros accesos al cuerpo de la página, por supuesto).


def _GetHtmlPage(self, addr): headers = { ''User-Agent'' : self.userAgent, '' Cookie'' : self.cookies} req = urllib2.Request(addr) response = urllib2.urlopen(req) print "ResponseInfo=" print response.info() resultsHtml = unicode(response.read(), self.encoding) return resultsHtml