Ich habe Probleme mit Unicode-Zeichen aus Text, der von verschiedenen Webseiten (auf verschiedenen Websites) abgerufen wurde. Ich benutze BeautifulSoup.
Das Problem ist, dass der Fehler nicht immer reproduzierbar ist. es funktioniert manchmal mit einigen Seiten, und manchmal barfs es, indem es ein wirft UnicodeEncodeError
. Ich habe so gut wie alles versucht, was mir einfällt, und dennoch nichts gefunden, das konsistent funktioniert, ohne einen Unicode-Fehler auszulösen.
Einer der Codeabschnitte, die Probleme verursachen, ist unten dargestellt:
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 eine Stapelverfolgung, die für einige Zeichenfolgen erstellt 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 Websites) möglicherweise codiert sind, während andere möglicherweise nicht codiert sind. Alle Websites haben ihren Sitz in Großbritannien und bieten Daten, die für den Verbrauch in Großbritannien bestimmt sind. Es gibt also keine Probleme im Zusammenhang mit der Internalisierung oder dem Umgang mit Texten, die nicht in Englisch verfasst sind.
Hat jemand irgendwelche Ideen, wie man das löst, damit ich dieses Problem konsequent beheben kann?
quelle
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'))
.$ export PYTHONIOENCODING=utf8
Antworten:
Sie müssen das Python Unicode HOWTO lesen . Dieser Fehler ist das allererste Beispiel .
Stoppen Sie grundsätzlich die
str
Konvertierung von Unicode in codierten Text / Bytes.Verwenden Sie stattdessen ordnungsgemäß
.encode()
, um die Zeichenfolge zu codieren:oder arbeiten vollständig in Unicode.
quelle
print
meine utf-8-Zeichenfolgen verwende, funktioniert es gut. Wenn ich jedoch die Ausgabe meiner Programme in eine Datei leite, wird a ausgelöstUnicodeEncodeError
. In der Tat, wenn die Ausgabe umgeleitet wird (in eine Datei oder eine Pipe), finde ich dassys.stdout.encoding
istNone
! Das Anheften.encode('utf-8')
löst das Problem.PYTHONIOENCODING=utf-8
stattdessen dh, drucken Sie Unicode-Zeichenfolgen und lassen Sie die Umgebung die erwartete Codierung festlegen..encode()
Methode zum Aufrufen.Dies ist ein klassischer Python-Unicode-Schmerzpunkt! Folgendes berücksichtigen:
Bis jetzt alles gut, aber wenn wir str (a) nennen, wollen wir sehen, was passiert:
Oh Dip, das wird niemandem nützen! Um den Fehler zu beheben, codieren Sie die Bytes explizit mit .encode und teilen Sie Python mit, welcher Codec verwendet werden soll:
Voil \ u00E0!
Das Problem ist, dass Python beim Aufrufen von str () die Standardzeichencodierung verwendet, um zu versuchen, die von Ihnen angegebenen Bytes zu codieren. In Ihrem Fall handelt es sich manchmal um Darstellungen von Unicode-Zeichen. Um das Problem zu beheben, müssen Sie Python mit .encode ('Whatever_unicode') mitteilen, wie mit der von Ihnen angegebenen Zeichenfolge umgegangen werden soll. Meistens sollten Sie mit utf-8 in Ordnung sein.
Eine hervorragende Darstellung zu diesem Thema finden Sie im PyCon-Vortrag von Ned Batchelder hier: http://nedbatchelder.com/text/unipain.html
quelle
None
Wert gestellt werden.Ich fand elegante Arbeit für mich, um Symbole zu entfernen und weiterhin Zeichenfolge als Zeichenfolge wie folgt beizubehalten:
Es ist wichtig zu beachten, dass die Verwendung der Option "Ignorieren" gefährlich ist, da dadurch die Unterstützung für Unicode (und Internationalisierung) stillschweigend aus dem Code entfernt wird, der sie verwendet (siehe Unicode konvertieren):
quelle
yourstring = yourstring.encode('utf-8', 'ignore').decode('utf-8')
os.path.join()
ist eine sehr gute Angewohnheit, wenn Sie mit der plattformübergreifenden Programmierung beginnen. :)Nun, ich habe alles versucht, aber es hat nicht geholfen. Nachdem ich herumgegoogelt hatte, dachte ich mir Folgendes und es half. Python 2.7 wird verwendet.
quelle
if sys.version_info.major < 3:
Ein subtiles Problem, das dazu führt, dass selbst der Druck fehlschlägt, besteht darin, dass Ihre Umgebungsvariablen falsch eingestellt sind, z. hier LC_ALL auf "C" gesetzt. In Debian raten sie davon ab, es einzustellen : Debian-Wiki im Gebietsschema
quelle
env|grep -E '(LC|LANG)'
.mc
im "Subshell-Modus" (Ctrl-O
) und habe auch vergessen, dass ich den folgenden Alias zu bash hinzugefügt habe :alias mc="LANG=en_EN.UTF-8 mc"
. Wenn ich also versuchte, schlecht geschriebene Skripte auszuführen, dieru_RU.UTF-8
intern verwendet werden, sterben sie einfach. Versuchte viele Sachen aus diesem Thread, bevor ich das eigentliche Problem entdeckte. :)Für mich hat funktioniert:
Hoffe das hilft jemandem.
quelle
Ich habe tatsächlich festgestellt, dass es in den meisten Fällen viel einfacher ist, nur diese Zeichen zu entfernen:
quelle
Das Problem ist, dass Sie versuchen, ein Unicode-Zeichen zu drucken, Ihr Terminal dies jedoch nicht unterstützt.
Sie können versuchen, das
language-pack-en
Paket zu installieren, um Folgendes zu beheben:Hier werden Aktualisierungen der englischen Übersetzungsdaten für alle unterstützten Pakete (einschließlich Python) bereitgestellt. Installieren Sie bei Bedarf ein anderes Sprachpaket (abhängig davon, welche Zeichen Sie drucken möchten).
Bei einigen Linux-Distributionen ist dies erforderlich, um sicherzustellen, dass die englischen Standard-Gebietsschemas ordnungsgemäß eingerichtet sind (damit Unicode-Zeichen von Shell / Terminal verarbeitet werden können). Manchmal ist es einfacher, es zu installieren, als es manuell zu konfigurieren.
Stellen Sie dann beim Schreiben des Codes sicher, dass Sie die richtige Codierung in Ihrem Code verwenden.
Zum Beispiel:
Wenn Sie immer noch ein Problem haben, überprüfen Sie Ihre Systemkonfiguration wie folgt:
Ihre Gebietsschemadatei (
/etc/default/locale
), die zoder:
Wert von
LANG
/LC_CTYPE
in der Shell.Überprüfen Sie, welches Gebietsschema Ihre Shell unterstützt:
Demonstration des Problems und der Lösung in einer neuen VM.
Initialisieren und Bereitstellen der VM (z. B. mithilfe
vagrant
):Siehe: verfügbare Ubuntu-Boxen . .
Drucken von Unicode-Zeichen (z. B. Markenzeichen
™
):Jetzt installieren
language-pack-en
:Jetzt sollte das Problem gelöst sein:
Versuchen Sie andernfalls den folgenden Befehl:
quelle
language-pack-en
mit Python oder dieser Frage zu tun? AFAIK, es kann Sprachübersetzungen für Nachrichten bereitstellen, hat aber nichts mit Codierung zu tun/etc/locale.gen
um sicherzustellen, dass sein Gebietsschema erstellt wird, bevor er es verwendet.LANG
von/etc/default/locale
(da/etc/locale.gen
nicht vorhanden) und ausgeführtlocale-gen
, aber es hat nicht geholfen. Ich bin mir nicht sicher, waslanguage-pack-en
genau funktioniert, da ich nicht viel Dokumentation gefunden habe und das Auflisten des Inhalts nicht viel hilft.LANG
/LC_CTYPE
/LC_ALL
statt ( zum BeispielLANG=C.UTF-8
).In der Schale:
Suchen Sie das unterstützte UTF-8-Gebietsschema mit dem folgenden Befehl:
Exportieren Sie es, bevor Sie das Skript ausführen, z.
oder manuell wie:
Testen Sie es, indem Sie ein Sonderzeichen drucken, z
™
.Oben in Ubuntu getestet.
quelle
Fügen Sie unten am Anfang Ihres Skripts (oder als zweite Zeile) eine Zeile hinzu:
Das ist die Definition der Python-Quellcode-Codierung. Weitere Infos in PEP 263 .
quelle
Hier ist eine Wiederholung einiger anderer sogenannter "Cop-out" -Antworten. Es gibt Situationen, in denen es trotz der hier geäußerten Proteste eine gute Lösung ist, die lästigen Charaktere / Saiten einfach wegzuwerfen.
Testen:
Ergebnisse:
Vorschlag: Vielleicht möchten Sie diese Funktion
toAscii
stattdessen benennen ? Das ist eine Frage der Präferenz.Dies wurde für Python 2 geschrieben. Für Python 3 möchten Sie wahrscheinlich
bytes(obj,"ascii")
eher als verwendenstr(obj)
. Ich habe das noch nicht getestet, aber ich werde es irgendwann tun und die Antwort überarbeiten.quelle
Ich habe immer den folgenden Code in die ersten beiden Zeilen der Python-Dateien eingefügt:
quelle
Einfache Hilfsfunktionen finden Sie hier .
quelle
backslashreplace
Fehlerhandler verwenden :u'\xa0'.encode('ascii', 'backslashreplace')
. Obwohl Sie eine solche Darstellung vermeiden und Ihre Umgebung so konfigurieren sollten, dass stattdessen Nicht-ASCII-Zeichen akzeptiert werden - es ist 2016!Fügen Sie einfach eine Variablencodierung hinzu ('utf-8')
quelle
Bitte öffnen Sie das Terminal und lösen Sie den folgenden Befehl aus:
quelle
Ich habe gerade folgendes benutzt:
Überprüfen Sie, was die Dokumentation dazu aussagt:
Löst es für mich. Simpel und einfach.
quelle
Die folgende Lösung hat bei mir funktioniert, habe gerade hinzugefügt
(stellt die Zeichenfolge als Unicode dar) vor meiner Zeichenfolge.
quelle
Leider funktioniert dies zumindest in Python 3 ...
Python 3
Manchmal liegt der Fehler in den Umgebungsvariablen und ist damit verbunden
wobei Fehler bei der Codierung ignoriert werden.
quelle
Ich hatte gerade dieses Problem und Google hat mich hierher geführt. Um die allgemeinen Lösungen hier zu ergänzen, hat dies für mich funktioniert:
Ich hatte diese Idee, nachdem ich Neds Präsentation gelesen hatte .
Ich behaupte jedoch nicht vollständig zu verstehen, warum dies funktioniert. Wenn also jemand diese Antwort bearbeiten oder einen Kommentar zur Erklärung abgeben kann, werde ich es begrüßen.
quelle
type
Wert? davor und danach? Ich denke, warum das funktioniert, ist, dass durch Ausführen einesunic += value
, das dasselbe ist, wieunic = unic + value
Sie einen String und einen Unicode hinzufügen, wobei Python dann Unicode für das Ergebnis annimmt,unic
dh den genaueren Typ (denken Sie darüber nach, wenn Sie dies tuna = float(1) + int(1)
,a
wird ein Float) und dannvalue = unic
verweistvalue
auf das neueunic
Objekt , das Unicode sein geschieht.Wir haben diesen Fehler beim Laufen festgestellt
manage.py migrate
in Django mit lokalisierten Geräten gespielt haben.Unsere Quelle enthielt die
# -*- coding: utf-8 -*-
Deklaration, MySQL war korrekt für utf8 konfiguriert und Ubuntu hatte das entsprechende Sprachpaket und die entsprechenden Werte/etc/default/locale
.Das Problem war einfach, dass dem Django-Container (wir verwenden Docker) das fehlte
LANG
env var .Einstellung
LANG
zuen_US.UTF-8
und Neustarten des Behälters vor dem Wieder laufenden Migrationen das Problem behoben.quelle
Viele Antworten hier (z. B. @agf und @Andbdrew) haben bereits die unmittelbarsten Aspekte der OP-Frage angesprochen.
Ich denke jedoch, dass es einen subtilen, aber wichtigen Aspekt gibt, der weitgehend ignoriert wurde und der für alle, die mich mögen, von großer Bedeutung ist, wenn sie versuchen, Codierungen in Python zu verstehen: Die Verwaltung der Zeichendarstellung in Python 2 und Python 3 ist völlig anders . Ich habe das Gefühl, dass ein großer Teil der Verwirrung damit zu tun hat, dass Leute über Codierungen in Python lesen, ohne sich der Version bewusst zu sein.
Ich empfehle jedem, der daran interessiert ist, die Grundursache des OP-Problems zu verstehen, zunächst Spolskys Einführung in Zeichendarstellungen und Unicode zu lesen und dann in Python 2 und Python 3 zu Batchelder auf Unicode zu wechseln .
quelle
Vermeiden Sie die Konvertierung der Variablen in str (Variable). Manchmal kann es das Problem verursachen.
Einfacher Tipp zu vermeiden:
Das obige Beispiel löst auch den Encode-Fehler.
quelle
Wenn Sie so etwas haben,
packet_data = "This is data"
tun Sie dies in der nächsten Zeile direkt nach der Initialisierungpacket_data
:quelle
Update für Python 3.0 und höher. Versuchen Sie Folgendes im Python-Editor:
Dadurch wird die Standardcodierung des Gebietsschemas des Systems auf das UTF-8-Format festgelegt.
Weitere Informationen finden Sie hier unter PEP 538 - Erzwingen des alten C-Gebietsschemas in ein UTF-8-basiertes Gebietsschema .
quelle
Ich hatte dieses Problem beim Versuch, Unicode-Zeichen auszugeben
stdout
, aber mitsys.stdout.write
anstatt zu drucken auszugeben (damit ich auch die Ausgabe in eine andere Datei unterstützen konnte).Aus der eigenen Dokumentation von BeautifulSoup habe ich dies mit der Codecs-Bibliothek gelöst:
quelle
Dieses Problem tritt häufig auf, wenn ein Django-Projekt mit Apache bereitgestellt wird. Weil Apache die Umgebungsvariable LANG = C in / etc / sysconfig / httpd setzt. Öffnen Sie einfach die Datei und kommentieren Sie diese Einstellung (oder ändern Sie sie in Ihren Geschmack). Oder verwenden Sie die Option lang des Befehls WSGIDaemonProcess. In diesem Fall können Sie verschiedene LANG-Umgebungsvariablen für verschiedene virtuelle Hosts festlegen.
quelle
Die empfohlene Lösung hat bei mir nicht funktioniert, und ich könnte damit leben, alle Nicht-ASCII-Zeichen zu löschen
was mich mit etwas gestrippt hat, das keine Fehler wirft.
quelle
Das wird funktionieren:
Ausgabe:
quelle