¿Hay una función estándar que convierta los encabezados http en un diccionario python, y uno para convertir de nuevo?Convertir encabezados http (cadena) a un diccionario python
Tendrían que soportar plegado de cabecera, por supuesto.
¿Hay una función estándar que convierta los encabezados http en un diccionario python, y uno para convertir de nuevo?Convertir encabezados http (cadena) a un diccionario python
Tendrían que soportar plegado de cabecera, por supuesto.
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.
* Tendrían que admitir plegado de cabecera * httplib no maneja plegado correctamente. Ver https: // github.com/shazow/urllib3/issues/3 –
@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
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'. –
No estoy del todo seguro, pero parece ser this lo largo de las líneas de lo que busca
espero que esto ayude
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
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
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()
.
¿De dónde sacas los encabezados http? – Mark
desde un objeto de archivo (hecho desde un socket) –