UnicodeEncodeError: le codec 'ascii' ne peut pas coder le caractère u '\ xa0' en position 20: l'ordinal n'est pas dans la plage (128)

1300

J'ai des problèmes avec les caractères unicode du texte récupéré à partir de différentes pages Web (sur différents sites). J'utilise BeautifulSoup.

Le problème est que l'erreur n'est pas toujours reproductible; il fonctionne parfois avec certaines pages, et parfois, il abat en lançant a UnicodeEncodeError. J'ai essayé à peu près tout ce à quoi je peux penser, et pourtant je n'ai rien trouvé qui fonctionne de manière cohérente sans lancer une sorte d'erreur liée à Unicode.

L'une des sections de code qui pose problème est illustrée ci-dessous:

agent_telno = agent.find('div', 'agent_contact_number')
agent_telno = '' if agent_telno is None else agent_telno.contents[0]
p.agent_info = str(agent_contact + ' ' + agent_telno).strip()

Voici une trace de pile produite sur CERTAINES chaînes lorsque l'extrait ci-dessus est exécuté:

Traceback (most recent call last):
  File "foobar.py", line 792, in <module>
    p.agent_info = str(agent_contact + ' ' + agent_telno).strip()
UnicodeEncodeError: 'ascii' codec can't encode character u'\xa0' in position 20: ordinal not in range(128)

Je soupçonne que cela est dû au fait que certaines pages (ou plus précisément, les pages de certains sites) peuvent être codées, tandis que d'autres peuvent ne pas l'être. Tous les sites sont basés au Royaume-Uni et fournissent des données destinées à la consommation au Royaume-Uni - il n'y a donc aucun problème lié à l'internalisation ou au traitement de texte écrit en autre chose qu'en anglais.

Quelqu'un at-il des idées sur la façon de résoudre ce problème afin que je puisse résoudre ce problème de manière cohérente?

Homunculus Reticulli
la source
1
Si vous obtenez ces erreurs en tant qu'utilisateur plutôt qu'en tant que développeur, consultez serverfault.com/questions/54591/… et askubuntu.com/questions/599808/…
That Brazilian Guy
J'ajouterai ce point n'utilisez pas onlinegdb.com/online_python_interpreter pour ce genre de choses. J'utilisais cet interpréteur pour tester des trucs et il n'est pas configuré correctement pour Unicode! Imprimait toujours au format 'B' \ nnn '' ... alors que tout ce que je voulais c'était un guillemet! J'ai essayé sur une machine virtuelle et cela a fonctionné immédiatement comme prévu en utilisant chr ()
JGFMK
4
Essayez ça import os; import locale; os.environ["PYTHONIOENCODING"] = "utf-8"; myLocale=locale.setlocale(category=locale.LC_ALL, locale="en_GB.UTF-8"); ... print(myText.encode('utf-8', errors='ignore')).
hhh
@hhh J'ai exécuté votre extrait NameError: le nom 'myText' n'est pas défini
KHAN irfan
9
Essayez de définir PYTHONIOENCODING dans le shell, avant d'exécuter votre script:$ export PYTHONIOENCODING=utf8
Noam Manos

Réponses:

1367

Vous devez lire le HOWTO Python Unicode . Cette erreur est le tout premier exemple .

Fondamentalement, arrêtez d'utiliser strpour convertir unicode en texte / octets codés.

À la place, utilisez correctement .encode()pour encoder la chaîne:

p.agent_info = u' '.join((agent_contact, agent_telno)).encode('utf-8').strip()

ou travailler entièrement en unicode.

agf
la source
23
D'accord! une bonne règle de base m'a appris à utiliser l'idée de "sandwich unicode". Votre script accepte les octets du monde extérieur, mais tout le traitement doit être effectué en unicode. Ce n'est que lorsque vous êtes prêt à sortir vos données qu'elles doivent être repoussées en octets!
Andbdrew
256
Au cas où quelqu'un d'autre serait confus par cela, j'ai trouvé une chose étrange: mon terminal utilise utf-8, et quand je utilise printmes cordes utf-8, cela fonctionne bien. Cependant, lorsque je redirige la sortie de mes programmes vers un fichier, il renvoie a UnicodeEncodeError. En fait, lorsque la sortie est redirigée (vers un fichier ou un tube), je trouve que sys.stdout.encodingc'est le cas None! Le virement .encode('utf-8')résout le problème.
drevicko
93
@drevicko: utilisez PYTHONIOENCODING=utf-8plutôt ie, imprimez les chaînes Unicode et laissez l'environnement définir le codage attendu.
jfs
1
@steinar: rien n'est valable dans tous les cas. En général, un utilisateur ne devrait pas se soucier que vous utilisez Python pour implémenter votre utilitaire (l'interface ne devrait pas changer si vous décidez de le réimplémenter dans une autre langue pour une raison quelconque) et donc vous ne devriez pas vous attendre à ce que cet utilisateur soit au courant de python- envvars spécifiques. C'est une mauvaise interface utilisateur pour forcer l'utilisateur à spécifier le codage des caractères; incorporer l'encodage des caractères dans le format de rapport si nécessaire. Remarque: aucun codage codé en dur ne peut être "par défaut sensible" dans le cas général.
jfs
13
C'est un conseil mauvais et déroutant. La raison pour laquelle les gens utilisent str est parce que l'objet N'EST PAS déjà une chaîne, il n'y a donc pas de .encode()méthode à appeler.
Cerin
434

C'est un point de douleur unicode classique en python! Considérer ce qui suit:

a = u'bats\u00E0'
print a
 => batsà

Tout va bien jusqu'à présent, mais si nous appelons str (a), voyons ce qui se passe:

str(a)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeEncodeError: 'ascii' codec can't encode character u'\xe0' in position 4: ordinal not in range(128)

Oh trempette, ça ne fera de bien à personne! Pour corriger l'erreur, codez les octets explicitement avec .encode et dites à python quel codec utiliser:

a.encode('utf-8')
 => 'bats\xc3\xa0'
print a.encode('utf-8')
 => batsà

Voil \ u00E0!

Le problème est que lorsque vous appelez str (), python utilise le codage de caractères par défaut pour essayer de coder les octets que vous lui avez donnés, qui dans votre cas sont parfois des représentations de caractères unicode. Pour résoudre le problème, vous devez dire à python comment gérer la chaîne que vous lui donnez en utilisant .encode ('any_unicode'). La plupart du temps, vous devriez bien utiliser utf-8.

Pour une excellente exposition sur ce sujet, voir le discours PyCon de Ned Batchelder ici: http://nedbatchelder.com/text/unipain.html

Andbdrew
la source
85
Note personnelle: Lorsque vous essayez de taper ".encode" ne tapez pas accidentellement ".unicode", alors demandez-vous pourquoi rien ne fonctionne.
Sautez Huffman
9
Bon conseil. Mais que faites-vous à la place lorsque vous utilisiez str (x) pour imprimer des objets qui peuvent ou non être des chaînes? str (x) fonctionne si x est un nombre, une date, une valeur booléenne ou une chaîne normale. Soudain, si c'est un unicode, il cesse de fonctionner. Existe-t-il un moyen d'obtenir le même comportement ou devons-nous maintenant ajouter une vérification IF pour tester si l'objet est une chaîne à utiliser .encode, et str () sinon?
Dirk R
La même question pourrait être posée avec Nonevaleur.
Vadorequest
210

J'ai trouvé un travail élégant pour supprimer les symboles et continuer à garder la chaîne en tant que chaîne comme suit:

yourstring = yourstring.encode('ascii', 'ignore').decode('ascii')

Il est important de noter que l'utilisation de l'option ignorer est dangereuse car elle supprime silencieusement toute prise en charge unicode (et internationalisation) du code qui l'utilise, comme on le voit ici (convertir unicode):

>>> u'City: Malmö'.encode('ascii', 'ignore').decode('ascii')
'City: Malm'
Max Korolevsky
la source
17
Tu as fait ma journée! Pour utf-8, il suffit de faire:yourstring = yourstring.encode('utf-8', 'ignore').decode('utf-8')
luca76
pour moi, cela a fonctionné mais mon cas était différent, j'enregistrais les noms de fichiers et j'avais "/" dans le nom et le chemin n'existait pas, donc je dois utiliser .replace ("/", "") et donc enregistré mon script. tout en ignorant l'ascii fonctionne également pour le cas 'utf-8'.
Akash Kandpal
1
@ harrypotter0 pour concaténer correctement les chemins d'accès aux fichiers os.path.join(), c'est une très bonne habitude lorsque vous commencez à faire de la programmation multiplateforme. :)
login_not_failed
152

eh bien j'ai tout essayé mais cela n'a pas aidé, après avoir fait des recherches sur Google, j'ai compris ce qui suit et cela a aidé. python 2.7 est en cours d'utilisation.

# encoding=utf8
import sys
reload(sys)
sys.setdefaultencoding('utf8')
Ashwin
la source
7
Ne fais pas ça. stackoverflow.com/questions/3828723/… , bien que lorsque vous avez des réponses comme celle-ci stackoverflow.com/a/31137935/2141635 vers le haut des résultats lorsque vous recherchez l'erreur, je peux voir pourquoi cela peut sembler une bonne idée.
Padraic Cunningham
21
J'ai essayé presque toutes les suggestions de ce sujet et aucune n'a vraiment fonctionné pour moi. Enfin j'ai essayé celui-ci. Et c'est vraiment LE SEUL qui a fonctionné simplement et bien. Si quelqu'un dit "Ne faites pas ça, alors venez avec une solution simple. Sinon, utilisez celle-ci. Parce que c'est une bonne copie de travail et une solution passée.
Richard de Ree
4
Comment cela pourrait-il être fait en python3? Serait heureux de savoir.
Kanerva Peter
3
Après tant de frustration, celui-ci a fonctionné. Merci beaucoup.
Avraham Zhurba
4
Je voudrais juste ajouter unif sys.version_info.major < 3:
contrat du professeur Falken a été rompu le
87

Un problème subtil entraînant l'échec de l'impression est que vos variables d'environnement sont incorrectes, par exemple. ici LC_ALL mis à "C". Dans Debian, ils découragent de le configurer: Debian wiki sur Locale

$ echo $LANG
en_US.utf8
$ echo $LC_ALL 
C
$ python -c "print (u'voil\u00e0')"
Traceback (most recent call last):
  File "<string>", line 1, in <module>
UnicodeEncodeError: 'ascii' codec can't encode character u'\xe0' in position 4: ordinal not in range(128)
$ export LC_ALL='en_US.utf8'
$ python -c "print (u'voil\u00e0')"
voilà
$ unset LC_ALL
$ python -c "print (u'voil\u00e0')"
voilà
maxpolk
la source
J'ai exactement le même problème, si mal que je ne l'ai pas vérifié avant de signaler . Merci beaucoup. Au fait, vous pouvez remplacer les deux premières commandes par env|grep -E '(LC|LANG)'.
Dmitry Verhoturov
Juste mes deux cents sur un mauvais problème d'encodage. Je l' utilise souvent mcen mode « sous - shell » ( Ctrl-O) et j'ai aussi oublié que j'ai ajouté l'alias suivant à bash: alias mc="LANG=en_EN.UTF-8 mc". Donc, quand j'ai essayé d'exécuter des scripts mal écrits qui dépendent de l' ru_RU.UTF-8intérieur, ils meurent. J'ai essayé beaucoup de choses de ce fil avant de découvrir le vrai problème. :)
login_not_failed
TU ES INCROYABLE. Dans GSUTIL, mon rsync échouait à cause exactement de ce problème. Correction du LC_ALL et tout fonctionne bien comme du vin. <3 MERCI <3
dsignr
27

Pour moi, ce qui a fonctionné était:

BeautifulSoup(html_text,from_encoding="utf-8")

J'espère que cela aide quelqu'un.

Animesh
la source
25

J'ai en fait constaté que dans la plupart de mes cas, le simple fait de supprimer ces caractères est beaucoup plus simple:

s = mystring.decode('ascii', 'ignore')
Phil LaNasa
la source
26
"Parfaitement" n'est généralement pas ce qu'il fait. Il jette des trucs que vous devez comprendre comment gérer correctement.
tripleee
7
simplement supprimer "ces" caractères (non anglais) n'est pas la solution car python doit prendre en charge toutes les langues, vous ne pensez pas?
alemol
8
Voté. Ce n'est pas du tout la bonne solution. Apprenez à travailler avec Unicode: joelonsoftware.com/articles/Unicode.html
Andrew Ferrier
4
Regardez, la façon la plus judicieuse de présenter cette réponse particulière est de cette manière: reconnaître que ascii confère un certain privilège à certaines langues et à certains utilisateurs - c'est la trappe d'échappement qui peut être exploitée pour les utilisateurs qui peuvent pirater un cursif, premier passage , script ensemble potentiellement pour un travail préliminaire avant la prise en charge complète de l'Unicode.
lol
5
Si j'écris un script qui a juste besoin d'imprimer du texte anglais sur stdout dans une application d'entreprise interne, je veux juste que le problème disparaisse. Tout ce qui fonctionne.
kagronick
25

Le problème est que vous essayez d'imprimer un caractère unicode, mais votre terminal ne le prend pas en charge.

Vous pouvez essayer d'installer le language-pack-enpackage pour résoudre ce problème:

sudo apt-get install language-pack-en

qui fournit des mises à jour des données de traduction en anglais pour tous les packages pris en charge (y compris Python). Installez un package de langue différent si nécessaire (selon les caractères que vous essayez d'imprimer).

Sur certaines distributions Linux, il est nécessaire pour s'assurer que les paramètres régionaux anglais par défaut sont correctement configurés (afin que les caractères unicode puissent être gérés par shell / terminal). Parfois, il est plus facile de l'installer que de le configurer manuellement.

Ensuite, lors de l'écriture du code, assurez-vous d'utiliser le bon encodage dans votre code.

Par exemple:

open(foo, encoding='utf-8')

Si vous avez toujours un problème, revérifiez la configuration de votre système, telle que:

  • Votre fichier de paramètres régionaux ( /etc/default/locale), qui devrait avoir par exemple

    LANG="en_US.UTF-8"
    LC_ALL="en_US.UTF-8"

    ou:

    LC_ALL=C.UTF-8
    LANG=C.UTF-8
  • Valeur de LANG / LC_CTYPEin shell.

  • Vérifiez les paramètres régionaux pris en charge par votre shell:

    locale -a | grep "UTF-8"

Démonstration du problème et de la solution dans une nouvelle machine virtuelle.

  1. Initialiser et provisionner la VM (par exemple en utilisant vagrant):

    vagrant init ubuntu/trusty64; vagrant up; vagrant ssh

    Voir: boîtes Ubuntu disponibles . .

  2. Impression de caractères unicode (comme le signe de marque comme ):

    $ python -c 'print(u"\u2122");'
    Traceback (most recent call last):
      File "<string>", line 1, in <module>
    UnicodeEncodeError: 'ascii' codec can't encode character u'\u2122' in position 0: ordinal not in range(128)
  3. Installation en cours language-pack-en:

    $ sudo apt-get -y install language-pack-en
    The following extra packages will be installed:
      language-pack-en-base
    Generating locales...
      en_GB.UTF-8... /usr/sbin/locale-gen: done
    Generation complete.
  4. Maintenant, le problème devrait être résolu:

    $ python -c 'print(u"\u2122");'
    
  5. Sinon, essayez la commande suivante:

    $ LC_ALL=C.UTF-8 python -c 'print(u"\u2122");'
    
kenorb
la source
1
Qu'est-ce que cela a language-pack-enà voir avec Python ou cette question? AFAIK, il peut fournir des traductions linguistiques aux messages mais n'a rien à voir avec l'encodage
Alastair McCormack
2
Sur certaines distributions Linux, il est nécessaire pour s'assurer que les paramètres régionaux anglais par défaut sont correctement configurés, en particulier lors de l'exécution du script Python sur le terminal. Cela a fonctionné pour moi à un moment donné. Voir: encodage de caractères
kenorb
Ah ok. Vous voulez dire si vous souhaitez utiliser un environnement local non anglais? Je suppose que l'utilisateur devra également modifier /etc/locale.genpour s'assurer que son environnement local est construit avant de l'utiliser?
Alastair McCormack
1
@AlastairMcCormack ont commenté sur LANGde /etc/default/locale(comme /etc/locale.genexist de does't) et RAN locale-gen, mais il n'a pas aidé. Je ne sais pas language-pack-enexactement ce qui se passe, car je n'ai pas trouvé beaucoup de documentation et en lister le contenu n'aide pas beaucoup.
kenorb
1
il est peu probable qu'il n'y ait pas déjà de paramètres régionaux utf-8 sur un système de bureau, c'est-à-dire qu'il n'est probablement pas nécessaire d'installer quoi que ce soit, il suffit de configurer LANG/ LC_CTYPE/ à la LC_ALLplace (par exemple, LANG=C.UTF-8).
jfs
19

En coquille:

  1. Recherchez les paramètres régionaux UTF-8 pris en charge à l'aide de la commande suivante:

    locale -a | grep "UTF-8"
  2. Exportez-le avant d'exécuter le script, par exemple:

    export LC_ALL=$(locale -a | grep UTF-8)

    ou manuellement comme:

    export LC_ALL=C.UTF-8
  3. Testez-le en imprimant des caractères spéciaux, par exemple :

    python -c 'print(u"\u2122");'

Ci-dessus testé dans Ubuntu.

kenorb
la source
Oui, c'est la meilleure réponse courte, nous ne pouvons pas modifier le code source pour utiliser .encode
Luat Nguyen - Neo.Mxn0
16

Ajoutez la ligne ci-dessous au début de votre script (ou comme deuxième ligne):

# -*- coding: utf-8 -*-

C'est la définition de l'encodage du code source python. Plus d'informations dans PEP 263 .

Andriy Ivaneyko
la source
2
Cela ne résout pas le problème lorsque le texte traité chargé à partir d'un fichier externe contient des encodages utf-8. Cela n'aide que pour les littéraux écrits dans le script python donné lui-même et n'est qu'un indice pour l'interpréteur python, mais n'a aucun impact sur le traitement de texte.
Mikaelblomkvistsson
16

Voici un remaniement de quelques autres réponses soi-disant "flic out". Il y a des situations dans lesquelles le simple fait de jeter les caractères / chaînes gênants est une bonne solution, malgré les protestations exprimées ici.

def safeStr(obj):
    try: return str(obj)
    except UnicodeEncodeError:
        return obj.encode('ascii', 'ignore').decode('ascii')
    except: return ""

Le tester:

if __name__ == '__main__': 
    print safeStr( 1 ) 
    print safeStr( "test" ) 
    print u'98\xb0'
    print safeStr( u'98\xb0' )

Résultats:

1
test
98°
98

Suggestion: vous pourriez vouloir nommer cette fonction à la toAsciiplace? C'est une question de préférence.

Cela a été écrit pour Python 2. Pour Python 3, je pense que vous voudrez utiliser bytes(obj,"ascii")plutôt que str(obj). Je n'ai pas encore testé cela, mais je vais à un moment donné et réviser la réponse.

BuvinJ
la source
8

Je mets toujours le code ci-dessous dans les deux premières lignes des fichiers python:

# -*- coding: utf-8 -*-
from __future__ import unicode_literals
Pereira
la source
6

Fonctions d'assistance simples trouvées ici .

def safe_unicode(obj, *args):
    """ return the unicode representation of obj """
    try:
        return unicode(obj, *args)
    except UnicodeDecodeError:
        # obj is byte string
        ascii_text = str(obj).encode('string_escape')
        return unicode(ascii_text)

def safe_str(obj):
    """ return the byte string representation of obj """
    try:
        return str(obj)
    except UnicodeEncodeError:
        # obj is unicode
        return unicode(obj).encode('unicode_escape')
Parag Tyagi
la source
Pour obtenir le bytestring se sont échappés (pour convertir la chaîne Unicode arbitraire octets utilisant le codage ascii), vous pouvez utiliser backslashreplacegestionnaire d'erreur: u'\xa0'.encode('ascii', 'backslashreplace'). Bien que vous deviez éviter une telle représentation et configurer votre environnement pour accepter des caractères non-ascii à la place - c'est 2016!
jfs
Bonne année @JFSebastian. Je viens d'être frustré par le problème Python-Unicode, puis j'ai finalement obtenu cette solution qui fonctionnait. Je n'en savais rien. Quoi qu'il en soit, merci pour le conseil.
Parag Tyagi
6

Ajoutez simplement à un encodage variable ('utf-8')

agent_contact.encode('utf-8')
Kairat Koibagarov
la source
4

Veuillez ouvrir le terminal et lancer la commande ci-dessous:

export LC_ALL="en_US.UTF-8"
Hồ Ngọc Vượng
la source
3

Je viens d'utiliser les éléments suivants:

import unicodedata
message = unicodedata.normalize("NFKD", message)

Vérifiez ce que la documentation en dit:

unicodedata.normalize (form, unistr) Retourne le formulaire de formulaire normal pour la chaîne Unicode unistr. Les valeurs valides pour le formulaire sont «NFC», «NFKC», «NFD» et «NFKD».

La norme Unicode définit diverses formes de normalisation d'une chaîne Unicode, basées sur la définition de l'équivalence canonique et de l'équivalence de compatibilité. En Unicode, plusieurs caractères peuvent être exprimés de différentes manières. Par exemple, le caractère U + 00C7 (LETTRE MAJUSCULE LATINE C AVEC CEDILLE) peut également être exprimé sous la forme de la séquence U + 0043 (LETTRE MAJUSCULE LATINE C) U + 0327 (COMBINAISON CEDILLE).

Pour chaque caractère, il existe deux formes normales: la forme normale C et la forme normale D. La forme normale D (NFD) est également connue sous le nom de décomposition canonique et traduit chaque caractère en sa forme décomposée. La forme normale C (NFC) applique d'abord une décomposition canonique, puis compose à nouveau les caractères pré-combinés.

En plus de ces deux formes, il existe deux formes normales supplémentaires basées sur l'équivalence de compatibilité. Dans Unicode, certains caractères sont pris en charge qui normalement seraient unifiés avec d'autres caractères. Par exemple, U + 2160 (ROMAN NUMERAL ONE) est vraiment la même chose que U + 0049 (LETTRE MAJUSCULE LATINE I). Cependant, il est pris en charge dans Unicode pour la compatibilité avec les jeux de caractères existants (par exemple gb2312).

La forme normale KD (NFKD) appliquera la décomposition de compatibilité, c'est-à-dire remplacer tous les caractères de compatibilité par leurs équivalents. La forme normale KC (NFKC) applique d'abord la décomposition de compatibilité, suivie de la composition canonique.

Même si deux chaînes Unicode sont normalisées et ont la même apparence pour un lecteur humain, si l'une a la combinaison de caractères et l'autre pas, elles peuvent ne pas être égales.

Le résout pour moi. Simple et facile.

Drag0
la source
3

La solution ci-dessous a fonctionné pour moi, vient d'être ajoutée

u "String"

(représentant la chaîne en unicode) avant ma chaîne.

result_html = result.to_html(col_space=1, index=False, justify={'right'})

text = u"""
<html>
<body>
<p>
Hello all, <br>
<br>
Here's weekly summary report.  Let me know if you have any questions. <br>
<br>
Data Summary <br>
<br>
<br>
{0}
</p>
<p>Thanks,</p>
<p>Data Team</p>
</body></html>
""".format(result_html)
Aravind Krishnakumar
la source
3

Hélas, cela fonctionne en Python 3 au moins ...

Python 3

Parfois, l'erreur se trouve dans les variables de l'environnement et se rencontre donc

import os
import locale
os.environ["PYTHONIOENCODING"] = "utf-8"
myLocale=locale.setlocale(category=locale.LC_ALL, locale="en_GB.UTF-8")
... 
print(myText.encode('utf-8', errors='ignore'))

où les erreurs sont ignorées dans le codage.

hhh
la source
2

Je viens d'avoir ce problème, et Google m'a conduit ici, alors juste pour ajouter aux solutions générales ici, c'est ce qui a fonctionné pour moi:

# 'value' contains the problematic data
unic = u''
unic += value
value = unic

J'ai eu cette idée après avoir lu la présentation de Ned .

Je ne prétends pas comprendre pleinement pourquoi cela fonctionne, cependant. Donc, si quelqu'un peut modifier cette réponse ou mettre un commentaire pour l'expliquer, je l'apprécierai.

pepoluan
la source
3
Quelle est la typevaleur? avant et après cela? Je pense que cela fonctionne parce qu'en faisant un unic += valuequi est le même que unic = unic + valuevous ajoutez une chaîne et un unicode, où python assume alors unicode pour la résultante, unicc'est-à-dire le type le plus précis (pensez quand vous faites cela a = float(1) + int(1), adevient un flottant) et value = unicpointe ensuite valuevers le nouvel unicobjet qui se trouve être unicode.
Tom Myddeltyn
2

Nous avons rencontré cette erreur lors de l'exécution manage.py migrate dans Django avec des appareils localisés.

Notre source contenait la # -*- coding: utf-8 -*-déclaration, MySQL était correctement configuré pour utf8 et Ubuntu avait le pack de langue et les valeurs appropriés dans/etc/default/locale .

Le problème était simplement que le conteneur Django (nous utilisons docker) manquait le LANG var env.

Réglage LANGde en_US.UTF-8et redémarrer le conteneur avant migrations réexécution résolu le problème.

Followben
la source
1

De nombreuses réponses ici (@agf et @Andbdrew par exemple) ont déjà abordé les aspects les plus immédiats de la question OP.

Cependant, je pense qu'il y a un aspect subtil mais important qui a été largement ignoré et qui compte beaucoup pour tous ceux qui comme moi se sont retrouvés ici tout en essayant de donner un sens aux encodages en Python: Python 2 vs Python 3, la gestion de la représentation des personnages est très différente . Je me sens comme un gros morceau de confusion a à voir avec les gens qui lisent sur les encodages en Python sans être au courant de la version.

Je suggère à toute personne intéressée à comprendre la cause première du problème OP de commencer par lire l' introduction de Spolsky aux représentations de caractères et Unicode, puis de passer à Batchelder sur Unicode en Python 2 et Python 3.

Simón Ramírez Amaya
la source
oui, mon erreur était sur python 2.7, 'a'.format (u'ñ'), et la bonne solution n'est pas d'utiliser .encode ('utf-8') mais d'utiliser toujours des chaînes unicode, (la valeur par défaut en python 3 ): u'a'.format (u'ñ '),
Rogelio
1

Essayez d'éviter la conversion de variable en str (variable). Parfois, cela peut provoquer le problème.

Astuce simple à éviter:

try: 
    data=str(data)
except:
    data = data #Don't convert to String

L'exemple ci-dessus résoudra également l'erreur Encode.

sam ruben
la source
cela ne fonctionne pas car vous rencontrerez juste l'erreur dans l'exception
Aurele Collinet
0

Si vous avez quelque chose comme packet_data = "This is data"ça, faites-le sur la ligne suivante, juste après l'initialisation packet_data:

unic = u''
packet_data = unic
Nandan Kulkarni
la source
0

J'ai eu ce problème en essayant de sortir des caractères Unicode stdout, mais avecsys.stdout.write , plutôt que d'imprimer (afin que je puisse également prendre en charge la sortie vers un fichier différent).

À partir de la propre documentation de BeautifulSoup , j'ai résolu cela avec la bibliothèque de codecs:

import sys
import codecs

def main(fIn, fOut):
    soup = BeautifulSoup(fIn)
    # Do processing, with data including non-ASCII characters
    fOut.write(unicode(soup))

if __name__ == '__main__':
    with (sys.stdin) as fIn: # Don't think we need codecs.getreader here
        with codecs.getwriter('utf-8')(sys.stdout) as fOut:
            main(fIn, fOut)
palswim
la source
0

Ce problème se produit souvent lorsqu'un projet django se déploie à l'aide d'Apache. Parce qu'Apache définit la variable d'environnement LANG = C dans / etc / sysconfig / httpd. Ouvrez simplement le fichier et commentez (ou modifiez votre version) ce paramètre. Ou utilisez l'option lang de la commande WSGIDaemonProcess, dans ce cas, vous pourrez définir différentes variables d'environnement LANG sur différents hôtes virtuels.

shmakovpn
la source
0

La solution recommandée n'a pas fonctionné pour moi, et je pouvais vivre avec le dumping de tous les caractères non ascii, donc

s = s.encode('ascii',errors='ignore')

ce qui m'a laissé quelque chose de dépouillé qui ne jette pas d'erreurs.

Gulzar
la source
0

Cela fonctionnera:

 >>>print(unicodedata.normalize('NFD', re.sub("[\(\[].*?[\)\]]", "", "bats\xc3\xa0")).encode('ascii', 'ignore'))

Production:

>>>bats
Huzefa Usama
la source
0

Dans le cas général de l'écriture de cette chaîne de codage non prise en charge (disons ) dans un fichier (par exemple ), cela fonctionnedata_that_causes_this_errorresults.txt

f = open("results.txt", "w")
  f.write(data_that_causes_this_error.encode('utf-8'))
  f.close()
Pe Dro
la source