2010-03-22 23 views
28

BaseHTTPHandler del módulo BaseHTTPServer no parece proporcionar ninguna forma conveniente de acceder a los parámetros de solicitud http. ¿Cuál es la mejor manera de analizar los parámetros GET de la ruta y los parámetros POST del cuerpo de la solicitud?Analizar los parámetros http GET y POST de BaseHTTPHandler?

En este momento, estoy usando esto para 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 = {} 

Esto funciona para la mayoría de los casos, pero me gustaría algo más robusto que se encarga de codificaciones y casos como parámetros vacíos correctamente. Idealmente, me gustaría algo pequeño e independiente, en lugar de un marco web completo.

Respuesta

5

Puede probar los módulos Werkzeug, la biblioteca base de Werkzeug no es demasiado grande y, si es necesario, puede simplemente extraer este código y listo.

El método devuelve un url_decode MultiDict y tiene soporte de codificación :)

A diferencia del método urlparse.parse_qs la versión Werkzeug se ocupa de:

  • codificación
  • valores múltiples
  • orden de clasificación

Si no tiene n para estos (o en el caso de la codificación, use Python 3) que no dude en utilizar las soluciones integradas.

2

¿Ha investigado utilizando bibliotecas como CherryPy? Proporcionan un camino mucho más rápido para manejar estas cosas que BaseHTTPServer.

2

Se proporciona soporte para los parámetros básicos de solicitud HTTP en el CGI module. El mecanismo recomendado para manejar los datos del formulario es la clase cgi.FieldStorage.

Para obtener los datos del formulario enviado, es mejor utilizar la clase FieldStorage. Las otras clases definidas en este módulo se proporcionan principalmente para compatibilidad con versiones anteriores. Crear una instancia exactamente una vez, sin argumentos. Esto lee el contenido del formulario de la entrada estándar o el entorno (según el valor de varias variables de entorno establecidas de acuerdo con el estándar CGI). Como puede consumir entrada estándar, debe crearse una instancia solo una vez.

La instancia FieldStorage se puede indexar como un diccionario de Python. Permite realizar pruebas de membresía con el operador in, y también admite el método de diccionario estándar keys() y la función incorporada len(). Los campos de formulario que contienen cadenas vacías se ignoran y no aparecen en el diccionario; para mantener dichos valores, proporcione un valor verdadero para el parámetro de palabra clave keep_blank_values ​​opcional al crear la instancia FieldStorage.

Por ejemplo, el siguiente código (que asume que la cabecera Content-Type y línea en blanco ya se han impreso) comprueba que el nombre de campos y addr están establecidos en una cadena no vacía:

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 biblioteca CGI no maneja codificaciones (como UTF -8) para usted, por lo que es menos adecuado que algunas de las otras bibliotecas disponibles. – Wolph

+0

La codificación se puede delegar al primer argumento similar a un archivo de FieldStorage. – gimel

+0

Es cierto, pero ¿para qué preocuparse cuando hay scripts que manejan esto para usted, incluyendo la captura de errores? No hay necesidad de reinventar la rueda. – Wolph

78

es posible que desee utilizar 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']} 

para Python 2, el módulo se llama urlparse en lugar de url.parse.

+2

Cabe señalar que urlparse en Python 2 no maneja las codificaciones, la versión de Python 3 sí lo admite. Además, para mantener el orden correcto, se debe usar 'parse_qsl' en lugar de' parse_qs', que devuelve una lista. – Wolph

8

mejor solución a un viejo problema:

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

Esto hará que los datos POST urlencoded del contenido del documento y analizarlo con un diccionario urldecoding adecuada

+0

Estaba intentando crear el servidor más básico que pudiera manejar las solicitudes de obtención y publicación en Python, y solo el tuyo funcionó para mí en el manejo de solicitudes POST. Esto fue escrito hace 3 años, ¡pero gracias! :) – harkirat1892

Cuestiones relacionadas