/ / six.u () cadena HTML que no se escapa - python, json, python-2.7

six.u () cadena HTML sin escape - python, json, python-2.7

Utilizando Python 2.7. Como parte de una respuesta JSON, una API devuelve la cadena:

<a href="https://about.twitter.com/products/tweetdeck" rel="nofollow">TweetDeck</a>

Estoy usando una biblioteca que internamente hace:

six.u(json.dumps(s))

json.dumps() salida es:

""<a href=\"https://about.twitter.com/products/tweetdeck\" rel=\"nofollow\">TweetDeck</a>""

Esta salida se puede decodificar correctamente con json.loads

Pero la llamada a six.u da:

u""<a href="https://about.twitter.com/products/tweetdeck" rel="nofollow">TweetDeck</a>""

Y tratando de decodificar esta cadena con json.loads arroja un error.

ValueError: Extra data: line 1 column 11 - line 1 column 86 (char 10 - 85)

Parece que la llamada a six.u un-escapó del href valor, pero no estoy completamente seguro de cómo solucionar este problema.

Respuestas

1 para la respuesta № 1

six.u() está destinado a literales de cadena unicode, no salida JSON. No debe usarlo para decodificar el JSON a una cadena Unicode.

Desde el six.u() documentacion:

Un literal unicode "falso". text Siempre debe ser un literal de cadena normal. En Python 2, u() devuelve unicode, y en Python 3, una cadena. Además, en Python 2, la cadena se decodifica con el unicode-escape codec, que permite que se pueda utilizar unicode escapes.

Énfasis mio.

En su lugar, descodifique la cadena si usa Python 2:

json_string = json.dumps(s)
if hasattr(json_string, "decode"):
# Python 2; decode to a Unicode value
json_string = json_string.decode("ascii")

o usa el unicode() funciona y captura el NameError en Python 3:

json_string = json.dumps(s)
try:
# Python 2; decode to a Unicode value from ASCII
json_string = unicode(json_string)
except NameError:
# Python 3, already Unicode
pass

o conjunto ensure_ascii a False al llamar json.dumps():

json_string = json.dumps(s, ensure_ascii=False)

Esto todavía puede devolver un str sin embargo, escriba Python 2, pero solo si la entrada no contiene más que datos ASCII únicamente, por lo que la salida se puede mezclar con seguridad unicode valores.

De cualquier manera, obtienes valores consistentes entre Python 2 y Python 3; los six.u() decodificar también decodificar uhhhh JSON Las secuencias de escape de Unicode a los puntos de código de Unicode, mientras que el resultado de Python 3 JSON los dejaría intactos. Con la decodificación usted mantendría el uhhhh secuencias en Python 2 y 3, con ensure_ascii obtendrías puntos de código Unicode en ambos.

Ya que esta es una biblioteca de terceros, yo presentó un informe de error; Realmente no puedes recuperarte de este error; no puede insertar barras invertidas adicionales por adelantado y luego eliminarlas después, ya que no puede distinguirlas de las barras invertidas normales.