UnicodeDecodeError: el códec 'utf8' no puede decodificar el byte 0xa5 en la posición 0: byte de inicio no válido

188

Estoy usando Python-2.6 CGIscripts pero encontré este error en el registro del servidor mientras lo hacía json.dumps(),

Traceback (most recent call last):
  File "/etc/mongodb/server/cgi-bin/getstats.py", line 135, in <module>
    print json.dumps(​​__getdata())
  File "/usr/lib/python2.7/json/__init__.py", line 231, in dumps
    return _default_encoder.encode(obj)
  File "/usr/lib/python2.7/json/encoder.py", line 201, in encode
    chunks = self.iterencode(o, _one_shot=True)
  File "/usr/lib/python2.7/json/encoder.py", line 264, in iterencode
    return _iterencode(o, 0)
UnicodeDecodeError: 'utf8' codec can't decode byte 0xa5 in position 0: invalid start byte

Aqui

​__get​data()La función vuelve dictionary {}.

Antes de publicar esta pregunta, me he referido a esta pregunta de SO.


ACTUALIZACIONES

La siguiente línea está dañando el codificador JSON,

now = datetime.datetime.now()
now = datetime.datetime.strftime(now, '%Y-%m-%dT%H:%M:%S.%fZ')
print json.dumps({'current_time': now}) // this is the culprit

Tengo una solución temporal para ello

print json.dumps( {'old_time': now.encode('ISO-8859-1').strip() })

Pero no estoy seguro de si es la forma correcta de hacerlo.

Deepak Ingole
fuente
1
Parece que tiene algunos datos de cadena en el diccionario que no se pueden codificar / decodificar. ¿Qué hay en el dict?
mgilson
@mgilson sí, maestro Entendí el problema, pero no sé cómo lidiar con él ... dicthalist, dict, python timestamp value
Deepak Ingole
1
@ Piloto - En realidad no. El verdadero problema está enterrado en algún lugar __getdata. No sé por qué estás obteniendo un personaje no decodificable. Puedes intentar crear parches en el dict para que funcione, pero en su mayoría solo piden más problemas más adelante. Intentaría imprimir el dict para ver dónde está el personaje no ascii. Luego descubra cómo se calculó / estableció ese campo y trabaje hacia atrás desde allí.
mgilson
1
Tuve el mismo error al intentar leer un archivo .csv que tenía algunos caracteres no ascii. Eliminar esos caracteres (como se sugiere a continuación) resolvió el problema.
Dmitriy R. Starson

Respuestas:

87

El error se debe a que hay algunos caracteres no ascii en el diccionario y no puede codificarse / decodificarse. Una forma simple de evitar este error es codificar tales cadenas con la encode()función siguiente (si aes la cadena con caracteres no ascii):

a.encode('utf-8').strip()
Santosh Ghimire
fuente
2
Como UTF-8 es compatible con el ASCII de 7 bits de la vieja escuela, simplemente debe codificar todo. Para los caracteres en el rango ASCII de 7 bits, esta codificación será un mapeo de identidad.
Tadeusz A. Kadłubowski
29
Esto no parece muy claro. Al importar un archivo csv, ¿cómo usa este código?
Dave
El mismo problema aparece para mí al ejecutar una consulta sqlalchemy, ¿cómo codificaría la consulta (no tiene .encode, ya que no es una cadena)?
c8999c 3f964f64
132

Cambié esto simplemente definiendo un paquete de códec diferente en el read_csv()comando:

encoding = 'unicode_escape'

P.ej:

import pandas as pd
data = pd.read_csv(filename, encoding= 'unicode_escape')
MSalty
fuente
1
Solo si está usandopandas
Valeriy
1
lo siento, esto no funcionó, nuevamente tuve el mismo error. pero cuando usé ('filename.csv', engine = 'python'). Esto funcionó.
basavaraj_S
117

Pruebe el siguiente fragmento de código:

with open(path, 'rb') as f:
  text = f.read()
Coral
fuente
77
Tenía en rlugar de rb. gracias por el recordatorio para agregar b!
Paul
1
Por defecto, la openfunción tiene 'r' como modo de solo lectura. rbsignifica modo binario de lectura.
Shiva
39

Su cadena tiene un asciicarácter no codificado.

Es posible que no pueda decodificar utf-8si ha necesitado usar otras codificaciones en su código. Por ejemplo:

>>> 'my weird character \x96'.decode('utf-8')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Python27\lib\encodings\utf_8.py", line 16, in decode
    return codecs.utf_8_decode(input, errors, True)
UnicodeDecodeError: 'utf8' codec can't decode byte 0x96 in position 19: invalid start byte

En este caso, la codificación es windows-1252lo que debe hacer:

>>> 'my weird character \x96'.decode('windows-1252')
u'my weird character \u2013'

Ahora que lo tienes Unicode, puedes codificarlo de forma segura utf-8.

JCF
fuente
1
He creado una página simple que puede ayudar a establecer la codificación de algunos "bytes misteriosos" inesperados; tripleee.github.io/8bit
tripleee
34

En la lectura csv, agregué un método de codificación:

import pandas as pd
dataset = pd.read_csv('sample_data.csv', header= 0,
                        encoding= 'unicode_escape')
Krishna prasad.m
fuente
16

Establezca el codificador predeterminado en la parte superior de su código

import sys
reload(sys)
sys.setdefaultencoding("ISO-8859-1")
HimalayaCoder
fuente
¡Creo que python3 no tiene setdefaultencoding en el módulo sys!
Anwar Hossain
14

A partir de 2018-05, esto se maneja directamente con decode, al menos para Python 3 .

Estoy usando el fragmento de abajo para invalid start bytey invalid continuation byteerrores de tipo. Agregar lo errors='ignore'arregló para mí.

with open(out_file, 'rb') as f:
    for line in f:
        print(line.decode(errors='ignore'))
aaronpenne
fuente
1
Por supuesto, esto silenciosamente descarta información. Una solución mucho mejor es descubrir qué se supone que debe estar allí y solucionar el problema original.
tripleee
14

Inspirado por @aaronpenne y @Soumyaansh

f = open("file.txt", "rb")
text = f.read().decode(errors='replace')
Punnerud
fuente
Obtuve "AttributeError: el objeto 'str' no tiene el atributo 'decode' '. ¿No estás seguro de qué salió mal?
Victor Wong
¿Incluiste b a la "rb"? La b es para abrir el archivo con formato de byte. Si solo usa r, es una cadena y no incluye decodificación.
Punnerud
14

Esta solución funcionó para mí:

import pandas as pd
data = pd.read_csv("training.csv", encoding = 'unicode_escape')
shiva
fuente
11

Solución simple:

import pandas as pd
df = pd.read_csv('file_name.csv', engine='python')
Gil Baggio
fuente
3
Gracias que ayudaron!
Ruben
Me alegro de ayudar a @Ruben
Gil Baggio
2
Gracias, esto me ayudó. Estaba trabajando en pandas. Gracias de nuevo
basavaraj_S
Feliz de ayudar @basavaraj_S
Gil Baggio
1
La única solución que me funciona de todas las presentadas aquí.
lunesco
7

La siguiente línea está dañando el codificador JSON,

now = datetime.datetime.now()
now = datetime.datetime.strftime(now, '%Y-%m-%dT%H:%M:%S.%fZ')
print json.dumps({'current_time': now}) // this is the culprit

Tengo una solución temporal para ello

print json.dumps( {'old_time': now.encode('ISO-8859-1').strip() })

Marcar esto como correcto como una solución temporal (no estoy seguro).

Deepak Ingole
fuente
5

Si los métodos anteriores no funcionan para usted, puede considerar cambiar la codificación del archivo csv.

Usando Excel:

  1. Abrir archivo csv usando Excel
  2. Vaya a la opción "Menú Archivo" y haga clic en "Guardar como"
  3. Haga clic en "Examinar" para seleccionar una ubicación para guardar el archivo
  4. Ingrese el nombre de archivo deseado
  5. Seleccione la opción CSV (delimitado por comas) (* .csv)
  6. Haga clic en el cuadro desplegable "Herramientas" y haga clic en "Opciones web"
  7. En la pestaña "Codificación", seleccione la opción Unicode (UTF-8) de la lista desplegable "Guardar este documento como"
  8. Guarda el archivo

Usando el Bloc de notas:

  1. Abrir archivo csv usando el bloc de notas
  2. Vaya a la opción "Archivo"> ​​"Guardar como"
  3. Luego, seleccione la ubicación del archivo
  4. Seleccione la opción Guardar como tipo como Todos los archivos ( . )
  5. Especifique el nombre del archivo con la extensión .csv
  6. En la lista desplegable "Codificación", seleccione la opción UTF-8.
  7. Haga clic en Guardar para guardar el archivo.

Al hacer esto, debería poder importar archivos csv sin encontrar el UnicodeCodeError.

Zuo
fuente
2

Después de probar todas las soluciones antes mencionadas, si aún arroja el mismo error, puede intentar exportar el archivo como CSV (una segunda vez si ya lo ha hecho). Especialmente si está utilizando scikit learn, es mejor importar el conjunto de datos como un archivo CSV.

Pasé horas juntos, mientras que la solución era así de simple. Exporte el archivo como CSV al directorio donde están instalados Anaconda o sus herramientas de clasificación e inténtelo.

Sushmita
fuente
2

Puede usar cualquier codificación estándar de su uso y entrada específicos.

utf-8 es el predeterminado

iso8859-1 También es popular para Europa occidental.

p.ej: bytes_obj.decode('iso8859-1')

ver: documentos

NoamG
fuente
1
Adivinar ciegamente la codificación puede producir más errores. Seleccionar iso8859-1 o cp1251, etc. sin saber realmente qué codificación usa el archivo eliminará el síntoma, pero producirá basura si adivinó mal. Si solo son unos pocos bytes, pueden pasar años antes de que note y corrija el error real .
tripleee