Solicitudes de Python que codifican datos POST

Versión: Python 2.7.3

Otras bibliotecas: Python-Requests 1.2.3, jinja2 (2.6)

Tengo un script que envía datos a un foro y el problema es que los caracteres que no son ASCII aparecen como basura. Por ejemplo, un nombre como André Téchiné aparece como André Téchiné.

Así es como se envían los datos:

1) Los datos se cargan inicialmente desde un archivo CSV codificado en UTF-8 así:

entries = [] with codecs.open(filename, 'r', 'utf-8') as f: for row in unicode_csv_reader(f.readlines()[1:]): entries.append(dict(zip(csv_header, row))) 

unicode_csv_reader se encuentra en la parte inferior de la página de documentación de Python CSV: http://docs.python.org/2/library/csv.html

Cuando u'Andr\xe9 T\xe9chin\xe9' el nombre de las entradas en el intérprete, veo el nombre como u'Andr\xe9 T\xe9chin\xe9' .

2) A continuación renderizo los datos a través de jinja2:

 tpl = tpl_env.get_template(u'forumpost.html') rendered = tpl.render(entries=entries) 

Cuando u'Andr\xe9 T\xe9chin\xe9' el nombre representado en el intérprete, vuelvo a ver lo mismo: u'Andr\xe9 T\xe9chin\xe9'

Ahora, si escribo la variable renderizada en un nombre de archivo como este, se muestra correctamente:

 with codecs.open('out.txt', 'a', 'utf-8') as f: f.write(rendered) 

Pero debo enviarlo al foro:

3) En el código de solicitud POST tengo:

 params = {u'post': rendered} headers = {u'content-type': u'application/x-www-form-urlencoded'} session.post(posturl, data=params, headers=headers, cookies=session.cookies) 

sesion es una sesion de solicitudes.

Y el nombre se muestra roto en la publicación del foro. He probado lo siguiente:

  • Omitir encabezados
  • Codificar renderizado como rendering.encode (‘utf-8’) (mismo resultado)
  • rendering = urllib.quote_plus (rendering) (sale como todo% XY)

Si escribo rendering.encode (‘utf-8’) veo lo siguiente:

 'Andr\xc3\xa9 T\xc3\xa9chin\xc3\xa9' 

¿Cómo podría solucionar el problema? Gracias.

Su cliente se comporta como debería, por ejemplo, ejecutando nc -l 8888 como un servidor y realizando una solicitud:

 import requests requests.post('http://localhost:8888', data={u'post': u'Andr\xe9 T\xe9chin\xe9'}) 

muestra:

 POST / HTTP/1.1 Host: localhost:8888 Content-Length: 33 Content-Type: application/x-www-form-urlencoded Accept-Encoding: gzip, deflate, compress Accept: */* User-Agent: python-requests/1.2.3 CPython/2.7.3 post=Andr%C3%A9+T%C3%A9chin%C3%A9 

Puedes comprobar que es correcto:

 >>> import urllib >>> urllib.unquote_plus(b"Andr%C3%A9+T%C3%A9chin%C3%A9").decode('utf-8') u'Andr\xe9 T\xe9chin\xe9' 
  • Compruebe que el servidor decodifica la solicitud correctamente. Podrías intentar especificar el conjunto de caracteres:

     headers = {"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8"} 

    el cuerpo solo contiene caracteres ASCII, por lo que no debería dañar y el servidor correcto ignoraría cualquier parámetro para el tipo x-www-form-urlencoded todos modos. Busque detalles sangrientos en datos de formulario codificados en URL

  • compruebe que el problema no es un artefacto de visualización, es decir, el valor es correcto pero se muestra incorrectamente

Intenta decodificar en utf8:

 unicode(my_string_variable, "utf8") 

o decodificar y codificar:

 sometext = gettextfromsomewhere().decode('utf-8') env = jinja2.Environment(loader=jinja2.PackageLoader('jinjaapplication', 'templates')) template = env.get_template('mypage.html') print template.render( sometext = sometext ).encode('utf-8')