unquote - urllib python 27
Codificación/decodificación URL con Python (3)
Estás fuera de suerte con stdlib, urllib.quote no funciona con Unicode. Si está usando django, puede usar django.utils.http.urlquote que funciona correctamente con unicode
Estoy tratando de codificar y almacenar, y decodificar argumentos en Python y perderme en algún lugar en el camino. Aquí están mis pasos:
1) Utilizo gtm_stringByEscapingForURLArgument
google toolkit para convertir un NSString correctamente para pasar a los argumentos HTTP.
2) En mi servidor (python), u''1234567890-/:;()$&@".,?!/'[]{}#%^*+=_//|~<>/u20ac/xa3/xa5/u2022.,?!/'''
estos argumentos de cadena como algo como u''1234567890-/:;()$&@".,?!/'[]{}#%^*+=_//|~<>/u20ac/xa3/xa5/u2022.,?!/'''
(tenga en cuenta que estas son las teclas estándar en un teclado de iphone en la vista "123" y la vista "# + =", el /u
/x
caracteres en algunos prefijos monetarios como libra, yen, etc.)
3) Llamo a urllib.quote(myString,'''')
en ese valor almacenado, presumiblemente a% -escape para el transporte al cliente para que el cliente pueda escapar del percentil.
El resultado es que obtengo una excepción cuando intento registrar el resultado de% de escape. ¿Hay algún paso crucial que pase por alto que deba aplicarse al valor almacenado con el formato / uy / x para convertirlo correctamente para enviarlo a través de http?
Actualización : la sugerencia marcada como la siguiente respuesta funcionó para mí. Sin embargo, estoy proporcionando algunas actualizaciones para completar los comentarios a continuación.
La excepción que recibí citó un problema con /u20ac
. No sé si fue un problema con eso específicamente, en lugar del hecho de que era el primer carácter Unicode en la cadena.
Ese /u20ac
char es el unicode para el símbolo ''euro''. Básicamente me di cuenta de que tendría problemas, a menos que utilizara el método de quote
urllib2.
La URL que codifica un Unicode "en bruto" realmente no tiene sentido. Lo que debes hacer es .encode("utf8")
para que tengas una codificación de bytes conocida y luego .quote()
eso.
La salida no es muy bonita, pero debería ser una codificación uri correcta.
>>> s = u''1234567890-/:;()$&@".,?!/'[]{}#%^*+=_/|~<>/u20ac/xa3/xa5/u2022.,?!/'''
>>> urllib2.quote(s.encode("utf8"))
''1234567890-/%3A%3B%28%29%24%26%40%22.%2C%3F%21%27%5B%5D%7B%7D%23%25%5E%2A%2B%3D_%5C%7C%7E%3C%3E%E2%82%AC%C2%A3%C2%A5%E2%80%A2.%2C%3F%21%27''
Recuerde que necesitará unquote()
y decode()
esto para imprimirlo correctamente si está depurando o lo que sea.
>>> print urllib2.unquote(urllib2.quote(s.encode("utf8")))
1234567890-/:;()$&@".,?!''[]{}#%^*+=_/|~<>€£¥•.,?!''
>>> # oops, nasty  means we''ve got a utf8 byte stream being treated as an ascii stream
>>> print urllib2.unquote(urllib2.quote(s.encode("utf8"))).decode("utf8")
1234567890-/:;()$&@".,?!''[]{}#%^*+=_/|~<>€£¥•.,?!''
Esto es, de hecho, lo que hacen las funciones django mencionadas en otra respuesta.
Las funciones django.utils.http.urlquote () y django.utils.http.urlquote_plus () son versiones de urllib.quote () y urllib.quote_plus () estándar de Python que funcionan con caracteres que no son ASCII. (Los datos se convierten a UTF-8 antes de la codificación).
Tenga cuidado si está aplicando cotizaciones o codificaciones adicionales para no alterar las cosas.
Quiero hacer una segunda observación de pycruft. los protocolos web han evolucionado a lo largo de décadas, y tratar con los diversos conjuntos de convenciones puede ser engorroso. ahora las URL no están explícitamente definidas para los caracteres, sino solo para los bytes (octetos). como una coincidencia histórica, las URL son uno de los lugares donde solo se puede asumir, pero no hacer cumplir o esperar de forma segura una codificación. sin embargo, existe una convención para preferir latin-1 y utf-8 sobre otras codificaciones aquí. por un tiempo, parecía que '' unicode por ciento escapa '' sería el futuro, pero nunca se entendieron.
es de suma importancia ser pedante exigente en esta área sobre la diferencia entre objetos unicode
y str
octeto (en Python <3.0; es decir, confusamente, objetos str
unicode y bytes
/ bytearray
objetos en Python> = 3.0). desafortunadamente, en mi experiencia, es por una serie de razones bastante difíciles de separar los dos conceptos en Python 2.x.
incluso más OT, cuando desee recibir solicitudes HTTP de terceros, no puede confiar absolutamente en que las URL se envíen en octetos con escapes %uxxxx
con codificación utf-8: puede haber tanto el escape %uxxxx
ocasional allí, y en al menos Firefox 2.x solía codificar las URL como latin-1 siempre que fuera posible, y como utf-8 solo cuando era necesario.