2010-03-22 12 views
28

BaseHTTPHandler aus dem BaseHTTPServer-Modul scheint keine bequeme Möglichkeit zum Zugriff auf HTTP-Anforderungsparameter zu bieten. Was ist der beste Weg, um die GET-Parameter aus dem Pfad und die POST-Parameter aus dem Anfragetext zu analysieren?http Get und POST-Parameter von BaseHTTPHandler?

Gerade jetzt, ich bin mit dieser für GET:

def do_GET(self): 
    parsed_path = urlparse.urlparse(self.path) 
    try: 
     params = dict([p.split('=') for p in parsed_path[4].split('&')]) 
    except: 
     params = {} 

Diese für die meisten Fälle funktioniert, aber ich möchte etwas robuster, die richtig Kodierungen und Fälle wie leere Parameter verarbeitet. Im Idealfall möchte ich etwas Kleines und Standalone statt eines vollständigen Web-Frameworks.

Antwort

5

Sie könnten versuchen, die Werkzeug Module, die Basis-Werkzeugbibliothek ist nicht zu groß und bei Bedarf können Sie einfach dieses Bit Code extrahieren und Sie sind fertig.

url_decode Die Methode gibt einen MultiDict und hat kodierend Unterstützung :)

Im Gegensatz zur Methode urlparse.parse_qs die Werkzeug-Version übernimmt:

  • Codierung
  • mehrere Werte
  • Sortierung

Wenn Sie keine n haben Setzen Sie diese ein (oder verwenden Sie Python 3 im Encoding-Modus), dann können Sie die integrierten Lösungen verwenden.

2

Haben Sie mit Bibliotheken wie CherryPy untersucht? Sie bieten einen viel schnelleren Weg zur Handhabung dieser Dinge als BaseHTTPServer.

2

Grundlegende HTTP-Anfrage Parameter Unterstützung ist in der CGI module zur Verfügung gestellt. Der empfohlene Mechanismus zur Verarbeitung von Formulardaten ist die cgi.FieldStorage-Klasse.

Um die übermittelten Formulardaten zu erhalten, verwenden Sie am besten die Klasse FieldStorage. Die anderen in diesem Modul definierten Klassen werden hauptsächlich aus Gründen der Abwärtskompatibilität bereitgestellt. Instantiiere es genau einmal ohne Argumente. Dies liest den Formularinhalt aus der Standardeingabe oder der Umgebung aus (abhängig vom Wert der verschiedenen Umgebungsvariablen, die gemäß dem CGI-Standard festgelegt wurden). Da die Standardeingabe konsumiert werden kann, sollte sie nur einmal instanziiert werden. Die FieldStorage Instanz kann wie ein Python-Wörterbuch indiziert werden. Es ermöglicht Mitgliedschafts-Tests mit dem Operator in und unterstützt außerdem die Standard-Dictionary-Methode keys() und die integrierte Funktion len(). Formularfelder, die leere Zeichenfolgen enthalten, werden ignoriert und erscheinen nicht im Wörterbuch. Um solche Werte beizubehalten, müssen Sie beim Erstellen der FieldStorage-Instanz einen gültigen Wert für den optionalen Schlüsselwortparameter keep_blank_values ​​angeben.

Zum Beispiel der folgende Code (die davon ausgeht, dass der Content-Type-Header und leere Zeile bereits gedruckt worden) prüft, ob die Felder Name und Adr beide auf eine nicht leere Zeichenfolge:

form = cgi.FieldStorage() 
if "name" not in form or "addr" not in form: 
    print "<H1>Error</H1>" 
    print "Please fill in the name and addr fields." 
    return 
print "<p>name:", form["name"].value 
print "<p>addr:", form["addr"].value 
#...further form processing here... 
+0

Die CGI-Bibliothek nicht Kodierungen umgehen (wie utf -8) für Sie, also ist es weniger geeignet als einige der anderen verfügbaren Bibliotheken. – Wolph

+0

Die Codierung kann an das dateiähnliche 1. Argument von FieldStorage delegiert werden. – gimel

+0

Richtig, aber warum sollten Sie sich kümmern, wenn es Skripte gibt, die das für Sie erledigen, einschließlich der Erfassung von Fehlern? Keine Notwendigkeit, das Rad neu zu erfinden. – Wolph

78

Sie möchten url.parse verwenden:

>>> from url.parse import urlparse, parse_qs 
>>> url = 'http://example.com/?foo=bar&one=1' 
>>> parse_qs(urlparse(url).query) 
{'foo': ['bar'], 'one': ['1']} 

Für Python 2 wird das Modul urlparse stattbenannt.

+2

Es sollte beachtet werden, dass URLParse in Python 2 keine Codierungen behandelt, die Python 3-Version unterstützt das nicht. Um die korrekte Reihenfolge beizubehalten, sollte zusätzlich 'parse_qsl' anstelle von 'parse_qs' verwendet werden, was eine Liste zurückgibt. – Wolph

8

bessere Lösung für eine alte Frage:

def do_POST(self): 
    length = int(self.headers.getheader('content-length')) 
    field_data = self.rfile.read(length) 
    fields = urlparse.parse_qs(field_data) 

Dies wird Urlencoded POST-Daten aus dem Dokumenteninhalt ziehen und analysiert es eine dict mit dem richtigen urldecoding

+0

Ich habe versucht, den grundlegendsten Server zu erstellen, der Anfragen in Python bearbeiten und senden kann, und nur Ihre hat bei der Bearbeitung von POST-Anfragen für mich funktioniert. Das wurde vor 3 Jahren geschrieben, aber danke! :) – harkirat1892