UnicodeEncodeError: 'ascii' codec ne peut pas encoder les caractères u'\xa3'
J'ai une feuille de calcul Excel que je suis en train de lire en ce que contient quelques £ signes.
Quand j'essaie de le lire en utilisant le xlrd module, j'obtiens l'erreur suivante:
x = table.cell_value(row, col)
x = x.decode("ISO-8859-1")
UnicodeEncodeError: 'ascii' codec can't encode character u'\xa3' in position 0: ordinal not in range(128)
Si je réécris ce à x.encode('utf-8') il s'arrête de lancer une erreur, mais malheureusement, quand je puis écrire les données de quelque part d'autre (latin-1), le £ signes sont tous devenus illisibles.
Comment puis-je résoudre ce problème, et de lire les £ signes correctement?
--- Mise à JOUR ---
Un certain type de lecteurs ont suggéré que je n'ai pas besoin de le décoder à tous, ou que je peux juste coder à Latin-1, quand j'en ai besoin. Le problème, c'est que j'ai besoin d'écrire les données dans un fichier CSV finalement, il me semble que l'objet de la crue de chaînes.
Si je ne suis pas d'encoder ou de décoder les données, ce qui arrive (après je l'ai ajouté à la chaîne dans un tableau appelé les éléments):
for item in items:
#item = [x.encode('latin-1') for x in item]
cleancsv.writerow(item)
File "clean_up_barnet.py", line 104, in <module>
cleancsv.writerow(item)
UnicodeEncodeError: 'ascii' codec can't encode character u'\u2022' in position 43: ordinal not in range(128)
J'obtiens la même erreur, même si je dé-commenter le Latin-1 ligne.
- Êtes-vous
.decode
-ing deux fois? - Je ne le pense pas. La ligne précédente est x = table.cell_value(ligne, col), de la xlrd module, même si - c'est peut-être de faire quelque chose de drôle?
Vous devez vous connecter pour publier un commentaire.
Votre extrait de code dit
x.decode
, mais vous avez une encoder erreur -- sensx
est Unicode déjà, donc, à "décoder", il doit d'abord être transformé en une chaîne d'octets (et c'est là que le codec par défautansi
est en place et échoue). Dans votre texte, vous pouvez dire "si je réécris ot de x.encoder"... ce qui semble impliquer que vous ne sais que x est Unicode.Donc ce que c'EST que vous avez fait, et ce que vous dire pour faire de l'encodage unicode
x
pour obtenir un code de chaîne d'octets, ou le décodage d'une chaîne d'octets dans un objet unicode?Je trouve ça dommage que vous pouvez appeler
encode
sur une chaîne d'octets, etdecode
sur un objet unicode, parce que je trouve ça semble conduire les utilisateurs à rien, mais la confusion... mais au moins, dans ce cas, vous semblent gérer pour propager la confusion (au moins pour moi;-).Si, comme il semble,
x
est en unicode, alors vous ne voulez jamais à "décoder" il -- vous pouvez encoder pour obtenir une chaîne d'octets avec un certain codec, par exemple, latin-1, si c'est ce que vous avez besoin pour une sorte de I/O (à des fins de votre propre programme interne d'utilisation je recommande de coller avec unicode tout le temps, seulement coder/décoder si et quand vous en avez absolument besoin, ou recevoir, codé chaînes d'octets pour les entrées /sorties fins).Un moyen très facile autour de tous les "'ascii' codec ne peut pas encoder les caractères..." des problèmes avec csvwriter est d'utiliser à la place unicodecsv, une baisse-dans le remplacement pour csvwriter.
Installer unicodecsv avec pip et puis vous pouvez l'utiliser exactement de la même façon, par exemple:
Pour ce qu'elle vaut: je suis l'auteur de
xlrd
.Ne
xlrd
produire de l'unicode?Option 1: Lire l'Unicode section au bas de la première page-écran de
xlrd
doc: Ce module présente toutes les chaînes de texte que Python unicode objets.Option 2:
print type(text), repr(text)
Vous dites """Si je réécris ce à x.encode('utf-8') il s'arrête de lancer une erreur, mais malheureusement, quand je puis écrire les données de quelque part d'autre (latin-1), le £ signes sont tous devenus illisibles.""" Bien sûr, si vous écrivez codé en UTF-8 de texte à un appareil en attente de latin1, il sera déformé. De quoi vous attendiez-vous?
Vous dites dans votre edit: """j'obtiens la même erreur, même si je dé-commenter le Latin-1 ligne""". C'est très rare, beaucoup plus probable, c'est que vous avez un peu différente de l'erreur (en mentionnant le latin1 codec plutôt que de l'ascii codec) dans une autre ligne de source (la décommenté latin1 ligne au lieu de l'writerow ligne). La lecture des messages d'erreur soigneusement sida compréhension.
Votre problème ici est que, en général, vos données ne sont PAS encodable en latin1; très peu de données du monde réel. Votre SIGNE dièse est encodable en latin1, mais ce n'est pas toutes vos données non-ASCII. Le caractère aléatoire est U+2022 BALLE qui n'est pas encodable en latin1.
Il vous aurait aidé à obtenir une meilleure réponse plus rapidement si vous l'aviez mentionné que vous travaillez sur Mac OS X ... l'habitude suspect pour un CSV-adapté encodage est
cp1252
(Windows), pasmac-roman
.Regardez de plus près: Vous avez un Unicode***Encoder***Erreur lors de l'appel de la décoder méthode.
La raison pour cela est que
decode
est destiné à convertir à partir d'une séquence d'octets (str
) à ununicode
objet. Mais, comme l'a dit John,xlrd
utilise déjà des chaînes Unicode, doncx
est déjà ununicode
objet.Dans cette situation, Python 2.x suppose que vous signifiait pour décoder un
str
objet, de sorte qu'il "utilement" crée pour vous. Mais en vue de convertir ununicode
à unstr
, il a besoin d'un codage, et choisit ASCII parce que c'est le plus petit dénominateur commun de l'encodage des caractères. Votre code est en fait interprété commequi échoue parce que
x
contient un caractère non-ASCII.Depuis
x
est déjà ununicode
objet, ledecode
est inutile. Cependant, maintenant que vous exécutez dans le problème que le Python 2.xcsv
module ne prend pas en charge Unicode. Vous devez convertir vos données enstr
objets.Ce serait correct, sauf que vous avez l'
•
caractère (U+2022 BALLE) en à vos données, et en Latin-1 ne peut pas le représenter. Il existe plusieurs façons de contourner ce problème:x.encode('latin-1', 'ignore')
d'enlever la balle (ou d'autres non-caractères Latin-1).x.encode('latin-1', 'replace')
à remplacer le point par un point d'interrogation.*
ou·
.Ces jours-ci, UTF-8 est largement pris en charge, donc il n'y a guère de raison d'utiliser un autre codage pour les fichiers texte.
xlrd
fonctionne avec Unicode, la chaîne que vous obtenez en retour est une chaîne Unicode. Le £-signe a point de code U+00A3, de sorte que la représentation de ladite chaîne doit êtreu'\xa3'
. Ce qui a été lu correctement; c'est la chaîne de caractères que vous devez travailler avec tout au long de votre programme.Lorsque vous écrivez ce (résumé, Unicode) chaîne de caractères quelque part, vous devez choisir un encodage. À ce stade, vous devriez
.encode
dans cet encodage, direlatin-1
.De travail avec xlrd, j'ai en une ligne ...xl_data.trouver(str(cell_value))... ce qui donne l'erreur:"'ascii' codec ne peut pas encoder les caractères u'\xdf' à la position 3: ordinal pas in range(128)". Toutes les suggestions sur les forums ont été inutiles pour mon allemand mots. Mais changer en: ...xl_data.trouver(de la cellule.valeur)... donne aucune erreur. Donc, je suppose, à l'aide de cordes comme arguments dans certaines commandes avec xldr a des problèmes d'encodage.