2010-02-15 13 views

Respuesta

5

en lugar de construir sus propios utilizando sockets, etc me gustaría utilizar httplib por lo tanto sería obtener los datos desde el servidor HTTP y analizar los encabezados en un diccionario por ejemplo

import httplib 
conn = httplib.HTTPConnection("www.python.org") 
conn.request("GET", "/index.html") 
r1 = conn.getresponse() 

dict = r1.getheaders() 
print(dict) 

da

[('Content-Length', '16788'), ('accept-rangos', 'bytes'), ('server', 'Apache/2.2.9 (Debian) DAV/2 SVN/1.5.1 mod_ssl/2.2.9 OpenSSL/0.9.8g mod_wsgi/2.5 Python/2.5.2 '), (' last-modified ',' Lun, 15 Feb 2010 07:30:46 GMT '), (' etag ',' "105800d-4194-47f9e9871d580" '), (' fecha ',' lun, 15 de febrero de 2010 21:34:18 GMT '), (' tipo de contenido ',' texto/html ')]

y métodos para enviar un diccionario como parte de una solicitud.

+0

* Tendrían que admitir plegado de cabecera * httplib no maneja plegado correctamente. Ver https: // github.com/shazow/urllib3/issues/3 –

+0

@PiotrDobrogost No creo que esté claro que el RFC dice eso: dice que DEBE ser posible combinar los múltiples campos de encabezado en un solo par de "nombre de campo: valor de campo". ... que httplib hace – Mark

+0

Eso es solo la mitad de la verdad :) La segunda mitad está en la oración anterior * Múltiples campos de encabezado de mensaje con el mismo nombre de campo PUEDEN estar presentes en un mensaje ** si y solo si ** el todo el campo-valor para ese campo de encabezado se define como una lista separada por comas [es decir, # (valores)]. * httplib pliega todos los encabezados con el mismo nombre, independientemente de la condición anterior. Vea el método [addheader] (http://hg.python.org/cpython/file/8527427914a2/Lib/httplib.py#l220) en 'httplib.py'. –

1

No estoy del todo seguro, pero parece ser this lo largo de las líneas de lo que busca

espero que esto ayude

3

En caso de que no encuentre ninguna biblioteca de la solución del problema, aquí está una solución probada ingenua:

def fold(header): 
    line = "%s: %s" % (header[0], header[1]) 
    if len(line) < 998: 
    return line 
    else: #fold 
    lines = [line] 
    while len(lines[-1]) > 998: 
     split_this = lines[-1] 
     #find last space in longest chunk admissible 
     split_here = split_this[:998].rfind(" ") 
     del lines[-1] 
     lines = lines + [split_this[:split_here]), 
         split_this[split_here:])] #this may still be too long 
               #hence the while on lines[-1] 
    return "\n".join(lines) 

def dict2header(data): 
    return "\n".join((fold(header) for header in data.items())) 

def header2dict(data): 
    data = data.replace("\n ", " ").splitlines() 
    headers = {} 
    for line in data: 
    split_here = line.find(":") 
    headers[line[:split_here]] = line[split_here:] 
    return headers 
+0

Me sorprendería si esto realmente funcionara en todos los casos. :) – badp

+0

Gracias, lo usaré y corregiré los errores que encuentre si no puedo obtener nada más. –

+0

He convertido esta respuesta en wiki de la comunidad, por lo que puede combinar las correcciones como/si es necesario. – badp

0

Y esta es mi versión sin para la iteración:

import re 
req_line = re.compile(r'(?P<method>GET|POST)\s+(?P<resource>.+?)\s+(?P<version>HTTP/1.1)') 
field_line = re.compile(r'\s*(?P<key>.+\S)\s*:\s+(?P<value>.+\S)\s*') 

def parse(http_post): 
    first_line_end = http_post.find('\n') 
    headers_end = http_post.find('\n\n') 
    request = req_line.match(
     http_post[:first_line_end] 
    ).groupdict() 
    headers = dict(
     field_line.findall(
      http_post[first_line_end:headers_end] 
     ) 
    ) 
    body = http_post[headers_end + 2:] 
    return request, headers, body 
1

Soy consciente de esta entrada es a partir de 2010, pero pensé que sería mejor hablar. Estoy de acuerdo con Mark's Post hasta que se asigna el dict.

Desde getheaders devuelve una lista de tuplas y el dict constructor construye diccionarios de pares de valores clave almacenados como tuplas puede crear lo que desea directamente:

import httplib 
conn = httplib.HTTPConnection("www.python.org") 
conn.request("GET", "/index.html") 
response = conn.getresponse() 

headers = dict(response.getheaders()) 
print(headers) 

Ahora que se obtiene:

{ 'content-length': '18891', 'accept-ranges': 'bytes', 'servidor': 'Apache/2.2.16 (Debian)', 'last-modified': 'Lun, 30 de mayo de 2011 19:50 : 25 GMT ',' etag ':' "105800d-49cb-4a48399368240" ',' fecha ':' Lun, 30 de mayo de 2011 21:29:32 GMT ',' tipo de contenido ':' text/html '}

Si quieres recuperar esas tuplas, llama al headers.items().

Cuestiones relacionadas