Ich habe Probleme beim Umgang mit Unicode-Zeichen aus Text, der von verschiedenen Webseiten (auf verschiedenen Websites) abgerufen wird. Ich verwende BeautifulSoup.
Das Problem ist, dass der Fehler nicht immer reproduzierbar ist; manchmal funktioniert es mit einigen Seiten, und manchmal kotzt es, indem es einen "UnicodeEncodeError" auslöst. Ich habe so ziemlich alles ausprobiert, was mir einfiel, aber ich habe noch nichts gefunden, das durchgängig funktioniert, ohne irgendeinen Unicode-Fehler zu verursachen.
Einer der Abschnitte des Codes, der Probleme verursacht, 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 bei der Ausführung des obigen Schnipsels für einige Zeichenfolgen erzeugt 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 Sites) verschlüsselt sein können, während andere nicht verschlüsselt sind. Alle Seiten haben ihren Sitz im Vereinigten Königreich und liefern Daten für den britischen Markt - es gibt also keine Probleme mit der Internalisierung oder dem Umgang mit Texten, die nicht in englischer Sprache verfasst sind.
Hat jemand eine Idee, wie ich dieses Problem lösen kann, so dass ich es KONSTANT beheben kann?
Sie müssen das Python Unicode HOWTO lesen. Dieser Fehler ist das allererste Beispiel.
Grundsätzlich sollten Sie aufhören, str
zur Konvertierung von Unicode in kodierten Text/Bytes zu verwenden.
Verwenden Sie stattdessen .encode()
, um den String zu kodieren:
p.agent_info = u' '.join((agent_contact, agent_telno)).encode('utf-8').strip()
oder arbeiten Sie vollständig in Unicode.
Dies ist ein klassischer Python Unicode Schmerzpunkt! Betrachten Sie das Folgende:
a = u'bats\u00E0'
print a
=> batsà
So weit alles gut, aber wenn wir str(a) aufrufen, sehen wir mal, 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 Schreck, das wird niemandem etwas nützen! Um den Fehler zu beheben, kodieren Sie die Bytes explizit mit .encode und sagen Sie Python, welchen Codec es verwenden soll:
a.encode('utf-8')
=> 'bats\xc3\xa0'
print a.encode('utf-8')
=> batsà
Voilà!
Das Problem ist, dass Python beim Aufruf von str() die Standard-Zeichenkodierung verwendet, um zu versuchen, die übergebenen Bytes zu kodieren, die in Ihrem Fall manchmal Darstellungen von Unicode-Zeichen sind. Um das Problem zu beheben, müssen Sie Python mitteilen, wie es mit der übergebenen Zeichenkette umgehen soll, indem Sie .encode('whatever_unicode') verwenden. Die meiste Zeit sollten Sie mit utf-8 auskommen.
Eine ausgezeichnete Darstellung dieses Themas finden Sie in Ned Batchelders PyCon-Vortrag hier: http://nedbatchelder.com/text/unipain.html
Ich habe festgestellt, dass es in den meisten meiner Fälle viel einfacher ist, diese Zeichen einfach zu entfernen:
s = mystring.decode('ascii', 'ignore')