Je lis et analyse un fichier Amazon XML et bien que le fichier XML affiche un ', lorsque j'essaie de l'imprimer, j'obtiens le message d'erreur suivant:
'ascii' codec can't encode character u'\u2019' in position 16: ordinal not in range(128)
D'après ce que j'ai lu en ligne jusqu'à présent, l'erreur provient du fait que le fichier XML est en UTF-8, mais Python veut le traiter comme un caractère codé ASCII. Existe-t-il un moyen simple d'éliminer l'erreur et de laisser mon programme imprimer le code XML tel qu'il se lit?
Probablement, votre problème est que vous l'avez analysé correctement et que vous essayez maintenant d'imprimer le contenu du fichier XML et que vous ne pouvez plus le faire, car il existe des caractères Unicode étrangers. Essayez d’encoder d’abord votre chaîne unicode en ascii:
unicodeData.encode('ascii', 'ignore')
la partie "ignorer" lui dira de simplement sauter ces caractères. À partir de la documentation python:
>>> u = unichr(40960) + u'abcd' + unichr(1972)
>>> u.encode('utf-8')
'\xea\x80\x80abcd\xde\xb4'
>>> u.encode('ascii')
Traceback (most recent call last):
File "<stdin>", line 1, in ?
UnicodeEncodeError: 'ascii' codec can't encode character '\ua000' in position 0: ordinal not in range(128)
>>> u.encode('ascii', 'ignore')
'abcd'
>>> u.encode('ascii', 'replace')
'?abcd?'
>>> u.encode('ascii', 'xmlcharrefreplace')
'ꀀabcd޴'
Vous voudrez peut-être lire cet article: http://www.joelonsoftware.com/articles/Unicode.html , que j’ai trouvé très utile comme didacticiel de base sur ce qui se passe. Après la lecture, vous finirez par ne plus avoir l'impression de deviner quelles commandes utiliser (ou du moins ce qui m'est arrivé).
Une meilleure solution:
if type(value) == str:
# Ignore errors even if the string is not proper UTF-8 or has
# broken marker bytes.
# Python built-in function unicode() can do this.
value = unicode(value, "utf-8", errors="ignore")
else:
# Assume the value object has proper __unicode__() method
value = unicode(value)
Si vous souhaitez en savoir plus sur pourquoi:
http://docs.plone.org/manage/troubleshooting/unicode.html#id1
Ne codez pas le codage de caractères de votre environnement dans votre script; affiche le texte Unicode directement à la place:
assert isinstance(text, unicode) # or str on Python 3
print(text)
Si votre sortie est redirigée vers un fichier (ou un canal); vous pouvez utiliser PYTHONIOENCODING
envvar pour spécifier le codage des caractères:
$ PYTHONIOENCODING=utf-8 python your_script.py >output.utf8
Sinon, python your_script.py
devrait fonctionner tel quel - vos paramètres régionaux sont utilisés pour coder le texte (sous POSIX, vérifiez: LC_ALL
, LC_CTYPE
, LANG
envvars - définissez LANG
sur un paramètre régional utf-8 si nécessaire).
Excellent post: http://www.carlosble.com/2010/12/understanding-python-and-unicode/
# -*- coding: utf-8 -*-
def __if_number_get_string(number):
converted_str = number
if isinstance(number, int) or \
isinstance(number, float):
converted_str = str(number)
return converted_str
def get_unicode(strOrUnicode, encoding='utf-8'):
strOrUnicode = __if_number_get_string(strOrUnicode)
if isinstance(strOrUnicode, unicode):
return strOrUnicode
return unicode(strOrUnicode, encoding, errors='ignore')
def get_string(strOrUnicode, encoding='utf-8'):
strOrUnicode = __if_number_get_string(strOrUnicode)
if isinstance(strOrUnicode, unicode):
return strOrUnicode.encode(encoding)
return strOrUnicode
J'ai écrit ce qui suit pour corriger les citations nuisibles non-ASCII et forcer la conversion en quelque chose d’utilisable.
unicodeToAsciiMap = {u'\u2019':"'", u'\u2018':"`", }
def unicodeToAscii(inStr):
try:
return str(inStr)
except:
pass
outStr = ""
for i in inStr:
try:
outStr = outStr + str(i)
except:
if unicodeToAsciiMap.has_key(i):
outStr = outStr + unicodeToAsciiMap[i]
else:
try:
print "unicodeToAscii: add to map:", i, repr(i), "(encoded as _)"
except:
print "unicodeToAscii: unknown code (encoded as _)", repr(i)
outStr = outStr + "_"
return outStr
Si vous devez imprimer une représentation approximative de la chaîne à l'écran plutôt que d'ignorer ces caractères non imprimables, veuillez essayer le paquetage unidecode
ici:
https://pypi.python.org/pypi/Unidecode
L'explication se trouve ici:
https://www.tablix.org/~avian/blog/archives/2009/01/unicode_transliteration_in_python/
Cela vaut mieux que d'utiliser u.encode('ascii', 'ignore')
pour une chaîne donnée u
, et cela peut vous éviter des maux de tête inutiles si la précision des caractères ne vous convient pas, mais que vous souhaitez tout de même avoir une lisibilité humaine.
Wirawan
Python 3.5, 2018
Si vous ne connaissez pas l'encodage mais que l'analyseur unicode rencontre des problèmes, vous pouvez ouvrir le fichier dans Notepad++
et sélectionner Encoding->Convert to ANSI
dans la barre du haut. Ensuite, vous pouvez écrire votre python comme ceci
with open('filepath', 'r', encoding='ANSI') as file:
for Word in file.read().split():
print(Word)
Vous pouvez utiliser quelque chose de la forme
s.decode('utf-8')
qui convertira une chaîne d'octets codée UTF-8 en une chaîne Python Unicode. Mais la procédure exacte à utiliser dépend de la manière dont vous chargez et analysez le fichier XML, par exemple. Si vous n'accédez jamais directement à la chaîne XML, vous devrez peut-être utiliser un objet décodeur du module codecs
.