web-dev-qa-db-fra.com

UnicodeDecodeError: le codec 'ascii' ne peut pas décoder l'octet 0xd1 en position 2: l'ordinal n'est pas dans la plage (128)

J'essaie de travailler avec un très grand ensemble de données contenant des caractères non standard. Je dois utiliser Unicode, conformément aux spécifications du travail, mais je suis perplexe. (Et peut-être que tout est faux.)

J'ouvre le CSV en utilisant:

 15     ncesReader = csv.reader(open('geocoded_output.csv', 'rb'), delimiter='\t', quotechar='"')

Ensuite, je tente de l'encoder avec:

name=school_name.encode('utf-8'), street=row[9].encode('utf-8'), city=row[10].encode('utf-8'), state=row[11].encode('utf-8'), Zip5=row[12], Zip4=row[13],county=row[25].encode('utf-8'), lat=row[22], lng=row[23])

J'encode tout sauf les lat et lng car ceux-ci doivent être envoyés à une API. Lorsque j'exécute le programme pour analyser l'ensemble de données dans ce que je peux utiliser, j'obtiens le traçage suivant.

Traceback (most recent call last):
  File "Push_into_db.py", line 80, in <module>
    main()
  File "Push_into_db.py", line 74, in main
    district_map = buildDistrictSchoolMap()
  File "Push_into_db.py", line 32, in buildDistrictSchoolMap
    county=row[25].encode('utf-8'), lat=row[22], lng=row[23])
UnicodeDecodeError: 'ascii' codec can't decode byte 0xd1 in position 2: ordinal not in range(128)

Je pense que je devrais vous dire que j'utilise python 2.7.2 et que cela fait partie d'une application générée sur Django 1.4. J'ai lu plusieurs articles sur ce sujet, mais aucun ne semble s'appliquer directement. Toute aide sera fortement appréciée.

Vous voudrez peut-être aussi savoir que certains des caractères non standard à l'origine du problème sont Ñ et peut-être É.

93
jelkimantis

Unicode n'est pas égal à UTF-8. Ce dernier n’est qu’un codage pour le premier.

Vous le faites dans le mauvais sens. Vous êtes en train de lire des données encodées , vous devez donc décode la chaîne codée en UTF-8 en une chaîne unicode.

Il suffit donc de remplacer .encode par .decode, et cela devrait fonctionner (si votre fichier .csv est codé en UTF-8).

Rien à avoir honte, cependant. Je parie que 3 programmeurs sur 5 ont eu du mal à comprendre cela, sinon plus;)

Mise à jour: Si vos données d'entrée ne sont pas codées au format et non UTF-8, vous devez .decode() avec le codage approprié, bien sûr. Si rien n'est donné, python suppose l'ASCII, qui échoue évidemment sur les caractères non-ASCII.

139
ch3ka

Ajoutez simplement ces lignes à vos codes:

import sys
reload(sys)
sys.setdefaultencoding('utf-8')
75
khelili miliana

pour Python 3 utilisateurs. tu peux faire

with open(csv_name_here, 'r', encoding="utf-8") as f:
    #some codes

ça marche aussi avec flask :)

15
screaminghard

Cette erreur s’explique principalement par le fait que le codage par défaut utilisé par python est ASCII. Par conséquent, si les données de chaîne à coder par encode('utf8') contiennent un caractère situé en dehors de ASCII plage, par ex. pour une chaîne telle que 'hgvcj 터 387', python renvoie une erreur car la chaîne n'est pas dans le format de codage attendu.

Si vous utilisez la version de python antérieure à la version 3.5, un correctif fiable consisterait à définir le codage par défaut utilisé par python sur utf8:

import sys
reload(sys)
sys.setdefaultencoding('utf8')
name = school_name.encode('utf8')

De cette façon, python pourrait anticiper les caractères d'une chaîne qui se trouvaient en dehors de la plage ASCII.

Toutefois, si vous utilisez python version 3.5 ou ultérieure, la fonction reload () n'est pas disponible. Vous devrez donc la réparer à l'aide de decode, par exemple.

name = school_name.decode('utf8').encode('utf8')
8
Temi Fakunle

Pour Python 3 utilisateurs:

changer l'encodage de 'ascii' à 'latin1' fonctionne.

En outre, vous pouvez essayer de trouver le codage automatiquement en lisant les 10 000 premiers octets à l'aide de l'extrait ci-dessous:

import chardet  
with open("dataset_path", 'rb') as rawdata:  
            result = chardet.detect(rawdata.read(10000))  
print(result)
2
Prithvi

si vous rencontrez ce problème lors de l'exécution de certbot lors de la création ou du renouvellement d'un certificat, veuillez utiliser la méthode suivante.

grep -r -P '[^\x00-\x7f]' /etc/Apache2 /etc/letsencrypt /etc/nginx

Cette commande a trouvé le caractère incriminé "´" dans un fichier .conf du commentaire. Après l'avoir retiré (vous pouvez éditer les commentaires à votre guise) et rechargé nginx, tout a fonctionné à nouveau.

Source: https://github.com/certbot/certbot/issues/5236

1
Anish Varghese

ouvert avec encodage UTF 16 en raison de lat et long. avec open (csv_name_here, 'r', encoding = "utf-16") en tant que f:

0
karthik r