2010-03-22 8 views
28

BaseHTTPHandler du module BaseHTTPServer ne semble pas offrir un moyen pratique d'accéder aux paramètres de requête http. Quelle est la meilleure façon d'analyser les paramètres GET à partir du chemin et les paramètres POST à ​​partir du corps de la demande?Analyser les paramètres http GET et POST à ​​partir de BaseHTTPHandler?

En ce moment, je suis en utilisant ce 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 = {} 

Cela fonctionne pour la plupart des cas, mais je voudrais quelque chose de plus robuste qui gère les encodages et des cas comme paramètres vides correctement. Idéalement, j'aimerais quelque chose de petit et autonome, plutôt qu'un framework web complet.

Répondre

5

Vous pouvez essayer les modules Werkzeug, la bibliothèque de base Werkzeug n'est pas trop grande et si nécessaire, vous pouvez simplement extraire ce peu de code et vous avez terminé.

La méthode url_decode retourne un MultiDict et a encodant le soutien :)

Contrairement à la méthode urlparse.parse_qs la version Werkzeug prend en charge:

  • encodage
  • plusieurs valeurs
  • ordre de tri

Si vous n'avez pas n eed pour ceux-ci (ou dans le cas de l'encodage, utilisez Python 3) que de se sentir libre d'utiliser les solutions intégrées.

2

Avez-vous étudié en utilisant des bibliothèques comme CherryPy? Ils fournissent un chemin beaucoup plus rapide pour gérer ces choses que BaseHTTPServer.

2

La prise en charge des paramètres de requête HTTP de base est fournie dans CGI module. Le mécanisme recommandé pour gérer les données de formulaire est la classe cgi.FieldStorage.

Pour obtenir les données de formulaire soumises, il est préférable d'utiliser la classe FieldStorage. Les autres classes définies dans ce module sont fournies principalement pour des raisons de compatibilité descendante. Instanciez-le exactement une fois, sans arguments. Cela permet de lire le contenu du formulaire à partir de l'entrée standard ou de l'environnement (en fonction de la valeur de diverses variables d'environnement définies conformément à la norme CGI). Comme il peut consommer une entrée standard, il ne doit être instancié qu'une seule fois.

L'instance FieldStorage peut être indexée comme un dictionnaire Python. Il permet le test d'appartenance avec l'opérateur in, et prend également en charge la méthode de dictionnaire standard keys() et la fonction intégrée len(). Les champs de formulaire contenant des chaînes vides sont ignorés et n'apparaissent pas dans le dictionnaire. Pour conserver ces valeurs, fournissez une valeur réelle pour le paramètre facultatif keep_blank_values ​​lors de la création de l'instance FieldStorage.

Par exemple, le code suivant (ce qui suppose que l'en-tête Content-Type et ligne blanche ont déjà été imprimées) vérifie que le nom et adr champs sont tous deux sur une chaîne non vide:

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

La bibliothèque CGI ne gère pas encodages (comme utf -8) pour vous c'est donc moins adapté que d'autres bibliothèques disponibles. – Wolph

+0

Le codage peut être délégué au premier argument de type FieldStorage. – gimel

+0

Vrai, mais pourquoi s'embêter quand il y a des scripts qui gèrent cela pour vous, y compris l'attrape des erreurs? Pas besoin de réinventer la roue. – Wolph

78

Vous pouvez utiliser url.parse:

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

pour Python 2, le module est nommé urlparse au lieu de url.parse.

+2

Il est à noter qu'urlparse dans Python 2 ne gère pas les encodages, la version Python 3 le supporte. De plus, pour maintenir l'ordre correct, 'parse_qsl' devrait être utilisé à la place de' parse_qs' qui retourne une liste. – Wolph

8

Une meilleure solution à une question ancienne:

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

Cela extraira les données urlencoded POST du contenu du document et d'analyser un dict avec decodage bon

+0

J'essayais de rendre le serveur le plus basique capable de gérer les requêtes get et post en Python, et seul le vôtre fonctionnait pour moi dans la gestion des requêtes POST. Cela a été écrit il y a 3 ans, mais merci! :) – harkirat1892