112 votes

Python Erreur d'encodage Unicode

Je lis et parsèse un fichier XML Amazon et alors que le fichier XML montre un ', lorsque j'essaie de l'imprimer, j'obtiens l'erreur suivante:

'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 encodé en ASCII. Y a-t-il un moyen simple de faire disparaître l'erreur et de faire en sorte que mon programme imprime le XML tel qu'il le lit?

0 votes

Je venais juste sur SO pour poster cette question. Y a-t-il un moyen facile de nettoyer une chaîne pour unicode() ?

0 votes

Veuillez également consulter cette réponse à une question connexe : « Python UnicodeDecodeError - est-ce que je comprends mal l'encodage ? »

200voto

Scott Stafford Points 13161

Probablement, votre problème est que vous l'avez analysé correctement, et maintenant vous essayez d'imprimer le contenu du XML et vous ne pouvez pas car il y a des caractères Unicode étrangers. Essayez d'encoder d'abord votre chaîne unicode en ascii :

unicodeData.encode('ascii', 'ignore')

la partie 'ignore' lui indiquera simplement de sauter ces caractères. Des documents de Python :

>>> # Python 2: u = unichr(40960) + u'abcd' + unichr(1972)
>>> u = chr(40960) + u'abcd' + chr(1972)
>>> u.encode('utf-8')
'\xea\x80\x80abcd\xde\xb4'
>>> u.encode('ascii')
Traceback (most recent call last):
  File "", 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 tutoriel de base sur ce qui se passe. Après la lecture, vous arrêterez de vous sentir comme si vous deviniez simplement quelles commandes utiliser (ou du moins c'est ce qui m'est arrivé).

1 votes

Je tente de rendre la chaîne suivante sécuritaire : 'foo « bar bar » df' (notez les guillemets courbes), mais cela ne fonctionne toujours pas pour moi.

0 votes

@Rosarch : Comment a échoué ? même erreur ? Et quelle règle de gestion des erreurs avez-vous utilisée ?

0 votes

@Rosarch, votre problème est probablement antérieur. Essayez ce code : # -- encodage : latin-1 -- u = u 'foo "bar bar" df' print u.encode('ascii', 'ignore') Pour vous, c'était probablement la conversion de votre chaîne EN unicode donnée l'encodage que vous avez spécifié pour le script python qui a généré l'erreur.

16voto

Paxwell Points 201

Une meilleure solution:

if type(value) == str:
    # Ignorer les erreurs même si la chaîne n'est pas en UTF-8 correct ou comporte
    # des octets de signalement incorrects.
    # La fonction intégrée de Python unicode() peut le faire.
    value = unicode(value, "utf-8", errors="ignore")
else:
    # Supposer que l'objet valeur possède une méthode __unicode__() appropriée
    value = unicode(value)

Si vous souhaitez en savoir plus sur la raison :

http://docs.plone.org/manage/troubleshooting/unicode.html#id1

3 votes

Ça ne aide pas avec le problème de OP : "can't encode character u'\u2019'". u'\u2019 est déjà Unicode.

8voto

J.F. Sebastian Points 102961

Ne codez pas en dur le codage des caractères de votre environnement à l'intérieur de votre script ; imprimez 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 tuyau), vous pouvez utiliser la variable d'environnement PYTHONIOENCODING pour spécifier le codage des caractères :

$ PYTHONIOENCODING=utf-8 python your_script.py >output.utf8

Autrement, python your_script.py devrait fonctionner tel quel -- vos paramètres régionaux sont utilisés pour encoder le texte (sur POSIX, vérifiez : les variables d'environnement LC_ALL, LC_CTYPE, LANG -- définissez LANG sur un paramètre régional utf-8 si nécessaire).

Pour imprimer de l'Unicode sur Windows, consultez cette réponse qui montre comment imprimer de l'Unicode sur la console Windows, dans un fichier ou en utilisant IDLE.

2voto

Ranvijay Points 72

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

0voto

David Z Points 49476

Vous pouvez utiliser quelque chose de la forme

s.decode('utf-8')

qui convertira une chaîne de bytes encodée en UTF-8 en une chaîne Unicode Python. Mais la procédure exacte à utiliser dépend de la manière précise dont vous chargez et analysez le fichier XML, par exemple, si vous n'accédez jamais directement à la chaîne XML, vous pourriez avoir à utiliser un objet décodeur du module codecs.

0 votes

Il est déjà encodé en UTF-8 L'erreur est spécifiquement: myStrings = deque([u 'Le texte de Dorf et Svoboda construit sur les str... et les sous-disciplines du génie informatique\u2019s.']) La chaîne est en UTF-8 comme vous pouvez le voir, mais elle est contrariée par le '\u2019' interne

0 votes

Oh, d'accord, je pensais que vous aviez un problème différent.

7 votes

@Alex B : Non, la chaîne est Unicode, pas Utf-8. Pour l' encoder en Utf-8 utilise '...'.encode('utf-8')

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X