Question UnicodeEncodeError: le codec 'ascii' ne peut pas encoder le caractère '\ xa0' en position 20: ordinal pas dans la plage (128)


J'ai des problèmes avec les caractères Unicode provenant du texte extrait de différentes pages Web (sur des sites différents). J'utilise BeautifulSoup.

Le problème est que l'erreur n'est pas toujours reproductible; il fonctionne parfois avec quelques pages, et parfois, il barre en jetant un UnicodeEncodeError. J'ai essayé à peu près tout ce que 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 à l'Unicode.

L'une des sections du 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 pense que c'est parce que certaines pages (ou plus précisément, les pages de certains sites) peuvent être encodées, alors que d'autres peuvent ne pas être codées. 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 pas de problèmes liés à l'internalisation ou au traitement d'un texte écrit dans autre chose que l'anglais.

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


937
2018-03-30 12:06


origine


Réponses:


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

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

Au lieu de cela, utilisez correctement .encode() pour encoder la chaîne:

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

ou travaillez entièrement en Unicode.


1052
2018-03-30 12:21



C'est un point de douleur classique python unicode! 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 qu'il 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, trempez, ça ne va pas faire du bien à tout le monde! Pour corriger l'erreur, encodez 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, ce qui dans votre cas sont parfois des représentations de caractères Unicode. Pour résoudre le problème, vous devez indiquer à python comment gérer la chaîne que vous lui donnez en utilisant .encode ('whatever_unicode'). La plupart du temps, vous devriez bien utiliser utf-8.

Pour une excellente exposition sur ce sujet, voir la conférence PyCon de Ned Batchelder ici: http://nedbatchelder.com/text/unipain.html


366
2018-03-30 12:25



J'ai trouvé un travail élégant autour de moi pour enlever les symboles et continuer à garder la chaîne comme suit:

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

Il est important de noter que l'utilisation de l'option ignore est dangereux car il supprime silencieusement tout support 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'

165
2017-08-20 10:13



Eh bien, j'ai tout essayé mais ça n'a pas aidé, après avoir googlé autour j'ai compris ce qui suit et ça m'a aidé. Python 2.7 est en cours d'utilisation.

# encoding=utf8
import sys
reload(sys)
sys.setdefaultencoding('utf8')

107
2017-09-02 13:10



Un problème subtil entraînant l'échec de l'impression est que les variables d'environnement soient incorrectes, par exemple. ici LC_ALL mis à "C". Dans Debian, ils déconseillent de le définir: Wiki Debian 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à

71
2017-12-02 17:58



En fait, j'ai trouvé que dans la plupart de mes cas, le simple fait de supprimer ces caractères est beaucoup plus simple:

s = mystring.decode('ascii', 'ignore')

26
2017-11-01 13:44



Pour moi, ce qui a fonctionné était:

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

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


24
2018-01-26 14:53



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

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

C'est la définition du codage du code source python. Plus d'infos dans PEP 263.


16
2017-08-08 10:17