Frage UnicodeEncodeError: 'ascii' Codec kann das Zeichen u '\ xa0' nicht an Position 20 codieren: Ordnungszahl nicht im Bereich (128)


Ich habe Probleme mit Unicode-Zeichen aus Text, der von verschiedenen Webseiten abgerufen wurde (auf verschiedenen Seiten). Ich benutze BeautifulSoup.

Das Problem ist, dass der Fehler nicht immer reproduzierbar ist; Manchmal funktioniert es mit einigen Seiten und manchmal mit einem UnicodeEncodeError. Ich habe fast alles ausprobiert, was mir einfällt, und dennoch habe ich nichts gefunden, was konsistent funktioniert, ohne irgendeinen Unicode-Fehler zu verursachen.

Einer der Codeabschnitte, die Probleme verursachen, wird unten angezeigt:

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()

Hier ist ein Stack-Trace, der auf SOME-Strings erzeugt wird, wenn das obige Snippet ausgeführt wird:

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)

Ich vermute, dass dies daran liegt, dass einige Seiten (oder genauer gesagt, Seiten von einigen der Seiten) kodiert sind, während andere möglicherweise unverschlüsselt sind. Alle Websites haben ihren Sitz im Vereinigten Königreich und stellen Daten bereit, die für den Konsum in Großbritannien bestimmt sind. Es gibt also keine Probleme im Zusammenhang mit der Internalisierung oder dem Umgang mit Texten, die nicht auf Englisch verfasst sind.

Hat jemand irgendwelche Ideen, wie man das löst, damit ich dieses Problem KONSEQUENT beheben kann?


937
2018-03-30 12:06


Ursprung


Antworten:


Sie müssen den Python lesen Unicode-HOWTO. Dieser Fehler ist der allererstes Beispiel.

Im Grunde, hör auf zu benutzen str Konvertieren von Unicode in codierten Text / Bytes.

Verwenden Sie stattdessen ordnungsgemäß .encode() um die Zeichenfolge zu codieren:

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

oder arbeite komplett in Unicode.


1052
2018-03-30 12:21



Dies ist ein klassischer Python-Unicode-Schmerzpunkt! Folgendes berücksichtigen:

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

Alles gut so weit, aber wenn wir str (a) nennen, mal sehen was passiert:

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 Dip, das wird niemandem gut tun! Um den Fehler zu beheben, kodieren Sie die Bytes explizit mit .encode und teilen Sie Python mit, welcher Codec verwendet werden soll:

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

Voil \ u00e0!

Das Problem ist, dass Python beim Aufruf von str () die Standardzeichencodierung verwendet, um zu versuchen, die Bytes zu codieren, die Sie ihm gegeben haben, was in Ihrem Fall manchmal Darstellungen von Unicode-Zeichen sind. Um das Problem zu beheben, müssen Sie Python mitteilen, wie Sie mit der Zeichenkette umgehen, die Sie mit .encode ('whatever_unicode') eingeben. In den meisten Fällen sollten Sie utf-8 verwenden.

Für eine hervorragende Ausstellung zu diesem Thema, siehe Ned Batchelders PyCon, sprechen Sie hier: http://nedbatchelder.com/text/unipain.html


366
2018-03-30 12:25



Ich fand elegante Arbeit für mich, um Symbole zu entfernen und weiterhin String als String zu halten:

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

Es ist wichtig zu beachten, dass die Option Ignorieren verwendet wird gefährlich weil es stillschweigend jede Unicode- (und Internationalisierungs-) Unterstützung aus dem Code entfernt, der es verwendet, wie hier zu sehen (Unicode konvertieren):

>>> u'City: Malmö'.encode('ascii', 'ignore').decode('ascii')
'City: Malm'

165
2017-08-20 10:13



Nun, ich habe alles versucht, aber es hat nicht geholfen. Nachdem ich gegoogelt hatte, dachte ich mir folgendes und es half. Python 2.7 wird verwendet.

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

107
2017-09-02 13:10



Ein subtiles Problem, das dazu führt, dass sogar der Druck fehlschlägt, sind falsche Umgebungsvariablen, z. Hier wird LC_ALL auf "C" gesetzt. In Debian raten sie davon ab, es zu setzen: Debian-Wiki auf Gebietsschema

$ 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



Ich habe tatsächlich herausgefunden, dass es in den meisten Fällen einfacher ist, diese Zeichen zu entfernen:

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

26
2017-11-01 13:44



Was für mich funktionierte, war:

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

Hoffe, das hilft jemandem.


24
2018-01-26 14:53



Fügen Sie die Zeile unten am Anfang Ihres Skripts (oder als zweite Zeile) hinzu:

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

Das ist die Definition von Python-Quellcode-Kodierung. Mehr Infos in PEP 263.


16
2017-08-08 10:17



Das Problem ist, dass Sie versuchen, ein Unicode-Zeichen zu drucken, aber Ihr Terminal unterstützt es nicht.

Sie können versuchen, zu installieren language-pack-en Paket um das zu beheben:

sudo apt-get install language-pack-en

Das bietet Updates für englische Übersetzungsdaten für alle unterstützten Pakete (einschließlich Python). Installieren Sie gegebenenfalls ein anderes Sprachpaket (abhängig davon, welche Zeichen Sie drucken möchten).

Bei einigen Linux-Distributionen ist es erforderlich, dass die standardmäßigen englischen Gebietsschemata korrekt eingerichtet sind (Unicode-Zeichen können also von Shell / Terminal gehandhabt werden). Manchmal ist es einfacher, es zu installieren, als es manuell zu konfigurieren.

Stellen Sie beim Schreiben des Codes sicher, dass Sie die richtige Codierung in Ihrem Code verwenden.

Beispielsweise:

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

Wenn Sie immer noch ein Problem haben, überprüfen Sie Ihre Systemkonfiguration wie:

  • Ihre Länderdatei (/etc/default/locale), die z.B.

    LANG="en_US.UTF-8"
    LC_ALL="en_US.UTF-8"
    
  • Wert von LANG/LC_CTYPE in der Schale.

  • Überprüfen Sie, welches Gebietsschema Ihre Shell unterstützt:

    locale -a | grep "UTF-8"
    

Demonstration des Problems und der Lösung in einer neuen VM.

  1. Initialisieren und Bereitstellen der VM (z. B. unter Verwendung von vagrant):

    vagrant init ubuntu/trusty64; vagrant up; vagrant ssh
    

    Sehen: verfügbare Ubuntu-Boxen..

  2. Drucken von Unicode-Zeichen (wie Markenzeichen wie ):

    $ 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. Jetzt installieren 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. Jetzt ist das Problem gelöst:

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

14
2017-08-13 12:07