UnicodeDecodeError: le codec 'utf8' ne peut pas décoder l'octet 0xa5 en position 0: octet de départ invalide


189

J'utilise des Python-2.6 CGIscripts mais j'ai trouvé cette erreur dans le journal du serveur en faisant 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

Ici,

​__get​data()retourne la fonction dictionary {}.

Avant de poster cette question, j'ai renvoyé celle de la question os SO.


MISES À JOUR

La ligne suivante fait mal à l'encodeur 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

J'ai une solution temporaire pour ça

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

Mais je ne suis pas sûr que ce soit la bonne façon de le faire.


1
Il semble que vous ayez des données de chaîne dans le dictionnaire qui ne peuvent pas être encodées / décodées. Qu'y a-t-il dans le dict?
mgilson

@mgilson yup master j'ai compris le problème mais donno comment y faire face .. dictalist, dict, python timestamp value
Deepak Ingole

1
@Pilot - Pas vraiment. Le vrai problème est enfoui quelque part __getdata. Je ne sais pas pourquoi vous obtenez un personnage non décodable. Vous pouvez essayer de trouver des correctifs sur le dict pour le faire fonctionner, mais ceux-ci ne demandent que plus de problèmes plus tard. J'essaierais d'imprimer le dict pour voir où se trouve le caractère non-ascii. Ensuite, déterminez comment ce champ a été calculé / défini et travaillez en arrière à partir de là.
mgilson


1
J'ai eu la même erreur en essayant de lire un fichier .csv qui contenait des caractères non-ascii. La suppression de ces caractères (comme suggéré ci-dessous) a résolu le problème.
Dmitriy R. Stars le

Réponses:


87

L'erreur est due au fait qu'il y a un caractère non-ascii dans le dictionnaire et qu'il ne peut pas être encodé / décodé. Un moyen simple d'éviter cette erreur consiste à encoder ces chaînes avec la encode()fonction suivante (si aest la chaîne avec un caractère non-ascii):

a.encode('utf-8').strip()

2
Comme UTF-8 est rétrocompatible avec l'ancien ASCII 7 bits, vous devez simplement tout encoder. Pour les caractères de la plage ASCII 7 bits, ce codage sera un mappage d'identité.
Tadeusz A. Kadłubowski

29
Cela ne semble pas très clair. Lors de l'importation d'un fichier csv, comment utilisez-vous ce code?
Dave le

Le même problème apparaît pour moi lors de l'exécution d'une requête sqlalchemy, comment encoder la requête (n'a pas de .encode, car ce n'est pas une chaîne)?
c8999c 3f964f64

133

J'ai changé cela simplement en définissant un package de codec différent dans la read_csv()commande:

encoding = 'unicode_escape'

Par exemple:

import pandas as pd
data = pd.read_csv(filename, encoding= 'unicode_escape')

1
Uniquement si vous utilisezpandas
Valeriy

1
désolé, cela n'a pas fonctionné, j'ai encore eu la même erreur. mais quand j'ai utilisé ('filename.csv', engine = 'python'). Cela a fonctionné.
basavaraj_S

117

Essayez l'extrait de code ci-dessous:

with open(path, 'rb') as f:
  text = f.read()

7
J'avais rau lieu de rb. merci pour le rappel à ajouter b!
Paul

1
Par défaut, la openfonction a «r» comme mode lecture seule. rbreprésente le mode binaire de lecture.
shiva le

39

Votre chaîne contient un asciicaractère non codé.

L'impossibilité de décoder avec utf-8peut se produire si vous avez besoin d'utiliser d'autres encodages dans votre code. Par exemple:

>>> '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

Dans ce cas, l'encodage est windows-1252donc à faire:

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

Maintenant que vous l'avez Unicode, vous pouvez encoder en toute sécurité utf-8.


1
J'ai créé une page simple qui peut aider à établir l'encodage de certains "octets mystères" inattendus; tripleee.github.io/8bit
tripleee

34

A la lecture csv, j'ai ajouté une méthode d'encodage:

import pandas as pd
dataset = pd.read_csv('sample_data.csv', header= 0,
                        encoding= 'unicode_escape')

16

Définissez l'encodeur par défaut en haut de votre code

import sys
reload(sys)
sys.setdefaultencoding("ISO-8859-1")

Je pense que python3 n'a pas setdefaultencoding dans le module sys!
Anwar Hossain

14

À partir de 2018-05, cela est géré directement avec decode, au moins pour Python 3 .

J'utilise l'extrait ci-dessous pour les erreurs de type invalid start byteet de invalid continuation bytetype. L'ajout l'a errors='ignore'corrigé pour moi.

with open(out_file, 'rb') as f:
    for line in f:
        print(line.decode(errors='ignore'))

1
Bien sûr, cela rejette silencieusement les informations. Une bien meilleure solution consiste à déterminer ce qui est censé être là et à résoudre le problème d'origine.
tripleee le

14

Inspiré par @aaronpenne et @Soumyaansh

f = open("file.txt", "rb")
text = f.read().decode(errors='replace')

J'ai "AttributeError: l'objet 'str' n'a pas d'attribut 'decode'". Vous ne savez pas ce qui ne va pas?
Victor Wong

Avez-vous inclus b dans le «rb»? Le b est pour ouvrir le fichier au format octet. Si vous utilisez simplement r, il s'agit d'une chaîne et n'inclut pas le décodage.
Punnerud

14

Cette solution a fonctionné pour moi:

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

11

Solution simple:

import pandas as pd
df = pd.read_csv('file_name.csv', engine='python')

3
Merci qui a aidé!
Ruben le

Heureux d'aider @Ruben
Gil Baggio

2
Merci cela m'a aidé. Je travaillais sur des pandas. Merci encore
basavaraj_S

Heureux d'aider @basavaraj_S
Gil Baggio

1
La seule solution qui fonctionne pour moi de toutes celles présentées ici.
lunesco

7

La ligne suivante fait mal à l'encodeur 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

J'ai une solution temporaire pour ça

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

Marquer cela comme correct en tant que solution temporaire (pas sûr).


5

Si les méthodes ci-dessus ne fonctionnent pas pour vous, vous voudrez peut-être envisager de modifier le codage du fichier csv lui-même.

Utilisation d'Excel:

  1. Ouvrez le fichier csv à l'aide d'Excel
  2. Accédez à l'option "Menu Fichier" et cliquez sur "Enregistrer sous"
  3. Cliquez sur "Parcourir" pour sélectionner un emplacement pour enregistrer le fichier
  4. Entrez le nom de fichier souhaité
  5. Sélectionnez l'option CSV (délimité par des virgules) (* .csv)
  6. Cliquez sur la liste déroulante "Outils" et cliquez sur "Options Web"
  7. Sous l'onglet "Encodage", sélectionnez l'option Unicode (UTF-8) dans la liste déroulante "Enregistrer ce document sous"
  8. Enregistrez le fichier

Utilisation du bloc-notes:

  1. Ouvrez le fichier csv à l'aide du bloc-notes
  2. Accédez à l'option "Fichier"> "Enregistrer sous"
  3. Ensuite, sélectionnez l'emplacement du fichier
  4. Sélectionnez l'option Enregistrer en tant que type sous Tous les fichiers ( . )
  5. Spécifiez le nom du fichier avec l'extension .csv
  6. Dans la liste déroulante "Encodage", sélectionnez l'option UTF-8.
  7. Cliquez sur Enregistrer pour enregistrer le fichier

En faisant cela, vous devriez pouvoir importer des fichiers csv sans rencontrer l'erreur UnicodeCodeError.


2

Après avoir essayé toutes les solutions de contournement susmentionnées, si la même erreur est toujours générée, vous pouvez essayer d'exporter le fichier au format CSV (une deuxième fois si vous avez déjà). Surtout si vous utilisez scikit learn, il est préférable d'importer l'ensemble de données sous forme de fichier CSV.

J'ai passé des heures ensemble, alors que la solution était aussi simple. Exportez le fichier au format CSV vers le répertoire où Anaconda ou vos outils de classification sont installés et essayez.


2

Vous pouvez utiliser n'importe quel codage standard de votre utilisation et de votre entrée spécifiques.

utf-8 est la valeur par défaut.

iso8859-1 est également populaire en Europe occidentale.

par exemple: bytes_obj.decode('iso8859-1')

voir: docs


1
Deviner aveuglément l'encodage est susceptible de produire plus d'erreurs. Sélectionner iso8859-1 ou cp1251 etc. sans savoir quel encodage le fichier utilise supprimera le symptôme, mais produira des déchets si vous vous trompez. S'il ne s'agit que de quelques octets, cela peut prendre des années avant de remarquer et de corriger la véritable erreur.
tripleee le

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.