UnicodeDecodeError: el codec ‘utf8’ no puede decodificar bytes en la posición 3-6: datos no válidos

¿Cómo funciona unicode en python2? Simplemente no entiendo.

Aquí descargo datos de un servidor y los analizo para JSON.

Traceback (most recent call last): File "/usr/local/lib/python2.6/dist-packages/eventlet-0.9.12-py2.6.egg/eventlet/hubs/poll.py", line 92, in wait readers.get(fileno, noop).cb(fileno) File "/usr/local/lib/python2.6/dist-packages/eventlet-0.9.12-py2.6.egg/eventlet/greenthread.py", line 202, in main result = function(*args, **kwargs) File "android_suggest.py", line 60, in fetch suggestions = suggest(chars) File "android_suggest.py", line 28, in suggest return [i['s'] for i in json.loads(opener.open('https://market.android.com/suggest/SuggRequest?json=1&query='+s+'&hl=de&gl=DE').read())] File "/usr/lib/python2.6/json/__init__.py", line 307, in loads return _default_decoder.decode(s) File "/usr/lib/python2.6/json/decoder.py", line 319, in decode obj, end = self.raw_decode(s, idx=_w(s, 0).end()) File "/usr/lib/python2.6/json/decoder.py", line 336, in raw_decode obj, end = self._scanner.iterscan(s, **kw).next() File "/usr/lib/python2.6/json/scanner.py", line 55, in iterscan rval, next_pos = action(m, context) File "/usr/lib/python2.6/json/decoder.py", line 217, in JSONArray value, end = iterscan(s, idx=end, context=context).next() File "/usr/lib/python2.6/json/scanner.py", line 55, in iterscan rval, next_pos = action(m, context) File "/usr/lib/python2.6/json/decoder.py", line 183, in JSONObject value, end = iterscan(s, idx=end, context=context).next() File "/usr/lib/python2.6/json/scanner.py", line 55, in iterscan rval, next_pos = action(m, context) File "/usr/lib/python2.6/json/decoder.py", line 155, in JSONString return scanstring(match.string, match.end(), encoding, strict) UnicodeDecodeError: 'utf8' codec can't decode bytes in position 3-6: invalid data 

¡¡gracias!!

EDIT: la siguiente cadena causa el error: '[{"t":"q","s":"abh\xf6ren"}]' . \xf6 debe decodificarse a ö (abhören)

La cadena que intenta analizar como JSON no está codificada en UTF-8. Lo más probable es que esté codificado en ISO-8859-1. Intente lo siguiente:

 json.loads(unicode(opener.open(...), "ISO-8859-1")) 

Eso manejará cualquier diéresis que puedan aparecer en el mensaje JSON.

Debería leer El Absoluto Mínimo Absoluto de Joel Spolsky. Todos los desarrolladores de software deben saber Absolutamente, positivamente acerca de los conjuntos de caracteres y Unicode (¡sin excusas!) . Espero que esto aclare algunos problemas que tiene alrededor de Unicode.

Mi solución es un poco divertida. Nunca pensé que sería tan fácil como guardar como con el códec UTF-8. Estoy usando notepad ++ (v5.6.8). No me di cuenta de que lo guardé con el códec ANSI inicialmente. Estoy usando un archivo separado para colocar todos los diccionarios localizados. Encontré mi solución en la pestaña ‘Codificación’ de mi Bloc de notas ++. Seleccioné ‘Codificación en UTF-8 sin BOM’ y la guardo. Funciona shinymente.

El error que está viendo significa que los datos que recibe del extremo remoto no son JSON válidos. JSON (según la especificación) normalmente es UTF-8, pero también puede ser UTF-16 o UTF-32 (en grande o en pequeño). El error exacto que está viendo significa que alguna parte de los datos no estaba UTF-8 válido (y tampoco era UTF-16 o UTF-32, ya que producirían errores diferentes).

Tal vez debería examinar la respuesta real que recibe del extremo remoto, en lugar de pasar los datos a json.loads() a json.loads() . En este momento, estás leyendo todos los datos de la respuesta en una cadena y asumiendo que es JSON. En su lugar, compruebe el tipo de contenido de la respuesta. Asegúrese de que la página web realmente reclame que le entregue JSON y no, por ejemplo, un mensaje de error que no sea JSON.

(Además, después de verificar la respuesta, use json.load() pasándole el objeto similar a un archivo devuelto por opener.open() , en lugar de leer todos los datos en una cadena y pasándolo a json.loads() .)

La solución para cambiar la encoding a Latin1 / ISO-8859-1 resuelve un problema que observé con html2text.py cuando se invoca en una salida de tex4ht. Lo uso para un recuento automático de palabras en los documentos de LaTeX: tex4ht los convierte a HTML, y luego html2text.py los elimina en texto puro para seguir contando a través de wc -w. Ahora, si, por ejemplo, un “Umlaut” alemán entra a través de una entrada de la base de datos de la literatura, ese proceso fallaría como html2text.py se quejaría, por ejemplo

UnicodeDecodeError: el codec ‘utf8’ no puede decodificar bytes en la posición 32243-32245: datos no válidos

Ahora, estos errores serían luego particularmente difíciles de rastrear, y esencialmente desea tener el Umlaut en su sección de referencias. Un simple cambio dentro de html2text.py desde

data = data.decode (encoding)

a

data = data.decode (“ISO-8859-1”)

resuelve ese problema; Si llama al script utilizando el archivo HTML como primer parámetro, también puede pasar la encoding como segundo parámetro y guardar la modificación.

En caso de que alguien tenga el mismo problema. Estoy usando vim con YouCompleteMe , no pude iniciar ycmd con este mensaje de error, lo que hice es: export LC_CTYPE="en_US.UTF-8" , el problema desapareció.

Pega esto en tu línea de comando:

 export LC_CTYPE="en_US.UTF-8" 

En su android_suggest.py, divida esa monstruosa statement de retorno de una sola línea en partes de one_step_at_a_time. Registre repr(string_passed_to_json.loads) algún lugar para que pueda verificarse después de que ocurra una excepción. Eye-ball los resultados. Si el problema no es evidente, edite su pregunta para mostrar la repetición.

unicode(urllib2.urlopen(url).read(), 'utf8') temporal: unicode(urllib2.urlopen(url).read(), 'utf8') : esto debería funcionar si lo que se devuelve es UTF-8.

urlopen().read() devuelve los bytes y usted tiene que decodificarlos en cadenas Unicode. También sería útil revisar el parche desde http://bugs.python.org/issue4733