2010-02-15 2 views

Antwort

5

Anstatt Ihre eigenen über Sockets bauen etc ich httplib So die Header in einen Wörterbuch die Daten von dem hTTP-Server und analysiere bekommen würde verwenden würde zB

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

dict = r1.getheaders() 
print(dict) 

gibt

[('Content-Length', '16788'), ('accept-Bereiche', '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 '), (' zuletzt geändert ',' Mo, 15 Feb 2010 07:30:46 GMT '), (' etag ',' "105800d-4194-47f9e9871d580" '), (' Datum ',' Mo, 15 Feb 2010 21:34:18 GMT '), (' content-type ',' text/html ')]

und Methoden für das Senden eines Wörterbuchs als Teil einer Anfrage.

+0

* Sie müssten Header-Faltung unterstützen * httplib funktioniert nicht richtig Falten. Siehe https: // github.com/shazow/urllib3/issues/3 –

+0

@PiotrDobrogost Ich denke nicht, das ist klar, die RFC sagt, dass - Es heißt, Es MÜSSEN möglich sein, die mehreren Header-Felder zu einem "Feldname: Feld-Wert" -Paar zu kombinieren. ... was httplib tut – Mark

+0

Das ist nur die Hälfte der Wahrheit :) Die zweite Hälfte ist im vorhergehenden Satz * Mehrere Nachrichten-Header-Felder mit dem gleichen Feld-Namen kann in einer Nachricht vorhanden sein ** wenn und nur wenn ** die Der gesamte Feldwert für dieses Kopfzeilenfeld ist als eine durch Kommas getrennte Liste [dh # (Werte)] definiert. * httplib faltet alle Kopfzeilen mit dem gleichen Namen, unabhängig von der oben genannten Bedingung. Siehe die Methode [addheader] (http://hg.python.org/cpython/file/8527427914a2/Lib/httplib.py#l220) in 'httplib.py'. –

1

Ich bin nicht ganz sicher, aber this scheint entlang der Linien zu sein, was Sie suchen

this helps

3

Falls Sie das Problem keine Bibliothek finden zu lösen, ist hier eine naive, nicht getestete Lösung:

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

Ich wäre überrascht, wenn dies in allen Fällen tatsächlich funktioniert. :) – badp

+0

Danke, ich werde das verwenden und beheben, welche Fehler ich finde, wenn ich nichts anderes bekommen kann. –

+0

Ich habe diese Antwort in ein Community-Wiki umgewandelt, sodass Sie die Fixes als/falls erforderlich zusammenführen können. – badp

0

Und das ist meine Version ohne Iteration:

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

Ich weiß, das Amt von 2010 ist, aber ich dachte, es am besten bis zu sprechen. Ich stimme mit Mark's Post überein, bis das Diktat zugewiesen ist.

Seit getheaders gibt eine Liste von Tupeln und die dict constructor baut Wörterbücher von Schlüssel-Wert-Paare gespeichert als Tupel können Sie erstellen, was Sie direkt wollen:

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

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

Jetzt erhalten Sie:

{ 'content-length': '18891', 'accept-ranges': 'Bytes', 'Server': 'Apache/2.2.16 (Debian)', 'Zuletzt geändert': 'Mo, 30. Mai 2011 19:50 : 25 GMT ',' Etag ':' "105800d-49cb-4a48399368240" ',' Datum ':' Mo, 30 Mai 2011 21:29:32 GMT ',' Inhaltstyp ':' text/html '}

Wenn Sie diese Tupel zurück wollen, rufen Sie headers.items().