Конвертировать заголовки http (строку) в словарь Python - PullRequest
7 голосов
/ 15 февраля 2010

Существует ли стандартная функция, которая преобразует заголовки http в словарь Python, и одна для преобразования обратно?

Конечно, они должны были бы поддерживать складывание заголовка.

Ответы [ 5 ]

5 голосов
/ 16 февраля 2010

Вместо того чтобы создавать свои собственные, используя сокеты и т. Д., Я бы использовал httplib Таким образом, получал бы данные с http-сервера и разбирал заголовки в словарь например,

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

dict = r1.getheaders()
print(dict)

дает

[('content-length', '16788'), ('accept-range', '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 '), (' последнее изменение ',' Пн, 15 февраля 2010 07:30:46 GMT '), (' etag ',' " 105800d-4194-47f9e9871d580 "'), (' date ',' Mon, 15 Feb 2010 21:34:18 GMT '), (' content-type ',' text / html ')]

и методы для отправки словаря как части запроса.

4 голосов
/ 16 февраля 2010

Если вы не нашли ни одной библиотеки, решающей проблему, вот наивное, непроверенное решение:

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
1 голос
/ 31 мая 2011

Я понимаю, что это сообщение с 2010 года, но я подумал, что лучше сказать об этом. Я согласен с сообщением Марка до тех пор, пока не будет назначен дикт.

Поскольку getheaders возвращает список кортежей, а конструктор dict создает словари из пар ключ-значение, хранящихся в виде кортежей, вы можете создавать то, что вам нужно:

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

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

Теперь вы получите:

{'content-length': '18891', 'accept-range': 'bytes', 'server': 'Apache / 2.2.16 (Debian)', 'last-updated': 'Пн, 30 мая 2011 19:50:25 GMT ',' etag ':' '105800d-49cb-4a48399368240 "', 'date': 'Пн, 30 мая 2011 21:29:32 GMT', 'content-type': 'text / HTML '}

Если вы хотите вернуть эти кортежи, позвоните headers.items().

1 голос
/ 15 февраля 2010

Я не совсем уверен, но это похоже соответствует тому, что вы ищете

Надеюсь, это поможет

0 голосов
/ 22 октября 2010

А это моя версия без итераций:

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...