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.

Deepak Ingole
la source
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()
Santosh Ghimire
la source
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')
MSalty
la source
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()
corail
la source
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.

JCF
la source
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')
Krishna prasad.m
la source
16

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

import sys
reload(sys)
sys.setdefaultencoding("ISO-8859-1")
HimalayanCoder
la source
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'))
Aaronpenne
la source
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')
Punnerud
la source
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')
Shiva
la source
11

Solution simple:

import pandas as pd
df = pd.read_csv('file_name.csv', engine='python')
Gil Baggio
la source
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).

Deepak Ingole
la source
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.

Zuo
la source
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.

Sushmita
la source
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

NoamG
la source
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