web-dev-qa-db-fra.com

Traiter les caractères mal encodés dans la chaîne unicode Python

Je traite des chaînes unicode renvoyées par la bibliothèque python-lastfm.

Je suppose que quelque part sur le chemin, la bibliothèque obtient un codage incorrect et renvoie une chaîne unicode pouvant contenir des caractères non valides.

Par exemple, la chaîne originale que j'attends dans la variable a est "Glück"

 >>> a 
 u'Gl\xfcck '
 >>> imprimer une trace 
 (dernier appel passé): 
 Fichier " ", ligne 1, dans 
 UnicodeEncodeError: le codec 'ascii' ne peut pas coder le caractère u '\ xfc' en position 2: l'ordinal n'est pas dans la plage (128) 

\ xfc est la valeur d'échappement 252, ce qui correspond au codage latin1 de "ü". D'une manière ou d'une autre, cela est incorporé dans la chaîne unicode de manière que python ne puisse pas gérer seul.

Comment est-ce que je convertis ceci en arrière une chaîne normale ou unicode qui contient l'original "Glück"? J'ai essayé de jouer avec les méthodes de décodage/encodage, mais j'ai soit obtenu un UnicodeEncodeError, soit une chaîne contenant la séquence\xfc.

14
strfry

Votre chaîne unicode est correcte:

>>> unicodedata.name(u"\xfc")
'LATIN SMALL LETTER U WITH DIAERESIS'

Le problème que vous voyez à l'invite interactive est que l'interpréteur ne sait pas quel encodage utiliser pour sortir la chaîne sur votre terminal, il se rabat donc sur le codec "ascii" - mais ce codec sait seulement comment traiter ASCII caractères. Cela fonctionne bien sur ma machine (parce que sys.stdout.encoding est "UTF-8" pour moi - probablement parce que quelque chose comme les paramètres de variable d'environnement diffère du vôtre)

>>> print u'Gl\xfcck'
Glück
7
Croad Langshan

Vous devez convertir votre chaîne unicode en une chaîne standard en utilisant un encodage, par exemple. utf-8:

some_unicode_string.encode('utf-8')

En dehors de cela: c'est une dupe de 

BeautifulSoup findall avec l'attribut de la classe - erreur de codage Unicode

et au moins dix autres questions connexes sur les SO. Recherche d'abord.

12
Andreas Jung

Au début de votre code, juste après les importations, ajoutez ces 3 lignes.

import sys  # import sys package, if not already imported
reload(sys)
sys.setdefaultencoding('utf-8')

Il remplacera le codage par défaut du système (ascii) pour le déroulement de votre programme.

Edit: Vous ne devriez pas faire cela à moins d’être sûr des conséquences, voir le commentaire ci-dessous. Ce message est également utile: Dangers de sys.setdefaultencoding ('utf-8')

4
az3

Ne pas str () transtyper en chaîne ce que vous avez dans les champs du modèle, tant que c'est déjà une chaîne unicode. (Oups, j'ai totalement manqué que cela ne soit pas lié à Django)

0
Artie