Mein Code kratzt nur eine Webseite und konvertiert sie dann in Unicode.
html = urllib.urlopen(link).read()
html.encode("utf8","ignore")
self.response.out.write(html)
Aber ich bekomme ein UnicodeDecodeError
:
Traceback (most recent call last):
File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/ext/webapp/__init__.py", line 507, in __call__
handler.get(*groups)
File "/Users/greg/clounce/main.py", line 55, in get
html.encode("utf8","ignore")
UnicodeDecodeError: 'ascii' codec can't decode byte 0xa0 in position 2818: ordinal not in range(128)
Ich gehe davon aus, dass der HTML-Code irgendwo einen falsch geformten Unicode-Versuch enthält. Kann ich einfach die Codebytes löschen, die das Problem verursachen, anstatt einen Fehler zu erhalten?
c2
Byte vorangestellt werden, sonst würde wahrscheinlich ein Dekodierungsfehler auftreten: hexutf8.com/?q=C2A0Antworten:
Update 2018:
Ab Februar 2018 mit Kompressionen wie
gzip
hat sich zu sehr beliebt (rund 73% aller Websites nutzen es, darunter große Websites wie Google, YouTube, Yahoo, Wikipedia, Reddit, Stack - Überlauf und Stapel Exchange Network Sites).Wenn Sie eine einfache Dekodierung wie in der ursprünglichen Antwort mit einer gezippten Antwort durchführen, wird ein Fehler wie der folgende angezeigt:
Um eine gzpipped-Antwort zu dekodieren, müssen Sie die folgenden Module hinzufügen (in Python 3):
Hinweis: In Python 2 würden Sie
StringIO
anstelle von verwendenio
Dann können Sie den Inhalt folgendermaßen analysieren:
Dieser Code liest die Antwort und legt die Bytes in einem Puffer ab. Das
gzip
Modul liest dann den Puffer mit derGZipFile
Funktion. Danach kann die komprimierte Datei wieder in Bytes eingelesen und am Ende in normal lesbaren Text dekodiert werden.Ursprüngliche Antwort von 2010:
Können wir den tatsächlichen Wert erhalten, für den verwendet wird?
link
?Außerdem tritt dieses Problem normalerweise hier auf, wenn wir versuchen,
.encode()
eine bereits codierte Bytezeichenfolge zu verwenden. Sie könnten also versuchen, es zuerst wie in zu dekodierenAls Beispiel:
Schlägt mit
Während:
Gelingt ohne Fehler. Beachten Sie, dass "Windows-1252" etwas ist, das ich als Beispiel verwendet habe . Ich habe das von Chardet bekommen und es hatte 0,5 Vertrauen, dass es richtig ist! (Nun, wie bei einer Zeichenfolge mit einer Länge von 1 Zeichen angegeben, was erwarten Sie?) Sie sollten dies in die Codierung der zurückgegebenen Byte-Zeichenfolge ändern
.urlopen().read()
Ihnen abgerufenen Inhalt gilt.Ein weiteres Problem, das ich dort sehe, ist, dass die
.encode()
Zeichenfolgenmethode die geänderte Zeichenfolge zurückgibt und die Quelle nicht an Ort und Stelle ändert. Es ist also nutzlos,self.response.out.write(html)
wenn HTML nicht die codierte Zeichenfolge aus html.encode ist (wenn Sie dies ursprünglich angestrebt haben).Überprüfen Sie, wie von Ignacio vorgeschlagen, die Quellwebseite auf die tatsächliche Codierung der zurückgegebenen Zeichenfolge von
read()
. Es befindet sich entweder in einem der Meta-Tags oder im ContentType-Header in der Antwort. Verwenden Sie das dann als Parameter für.decode()
.Beachten Sie jedoch, dass nicht davon ausgegangen werden sollte, dass andere Entwickler verantwortlich genug sind, um sicherzustellen, dass die Deklarationen für Header und / oder Metazeichensätze mit dem tatsächlichen Inhalt übereinstimmen. (Was eine PITA ist, ja, ich sollte wissen, ich war einer von denen vorher).
quelle
encoded_str = decoded_str.encode("utf8")
raise IOError, 'Not a gzipped file'
. Was ist der Fehler, den ich gemacht habe?Dekodieren Sie die Zeichenfolge, die Sie zurückerhalten, entweder mit dem Zeichensatz im entsprechenden
meta
Tag in der Antwort oder imContent-Type
Header und codieren Sie sie dann.Die Methode
encode(encoding, errors)
akzeptiert benutzerdefinierte Handler für Fehler. Die Standardwerteignore
sind außerdem:Siehe https://docs.python.org/3/library/stdtypes.html#str.encode
quelle
Als Erweiterung der Antwort von Ignacio Vazquez-Abrams
Manchmal ist es wünschenswert, Akzente aus Zeichen zu entfernen und das Basisformular zu drucken. Dies kann mit erreicht werden
Möglicherweise möchten Sie auch andere Zeichen (z. B. Interpunktion) in die nächstgelegenen Entsprechungen übersetzen. Beispielsweise wird das Unicode-Zeichen RIGHT SINGLE QUOTATION MARK beim Codieren nicht in ein ASCII-APOSTROPHE konvertiert.
Es gibt zwar effizientere Möglichkeiten, dies zu erreichen. Weitere Informationen finden Sie in dieser Frage. Wo befindet sich Pythons "beste ASCII-Datenbank für diesen Unicode"?
quelle
Verwenden Sie Unidecode - es konvertiert sogar seltsame Zeichen sofort in ASCII und konvertiert sogar Chinesisch in phonetische ASCII.
dann:
quelle
Ich benutze diese Hilfsfunktion in allen meinen Projekten. Wenn der Unicode nicht konvertiert werden kann, wird er ignoriert. Dies knüpft an eine Django-Bibliothek an, aber mit ein wenig Recherche könnte man sie umgehen.
Ich erhalte nach dieser Verwendung keine Unicode-Fehler mehr.
quelle
Für defekte Konsolen wie
cmd.exe
und HTML-Ausgabe können Sie immer verwenden:Dadurch bleiben alle Nicht-ASCII-Zeichen erhalten, während sie in reinem ASCII und HTML gedruckt werden können.
WARNUNG : Wenn Sie dies im Produktionscode verwenden, um Fehler zu vermeiden, stimmt höchstwahrscheinlich etwas in Ihrem Code nicht . Der einzig gültige Anwendungsfall hierfür ist das Drucken auf eine Nicht-Unicode-Konsole oder die einfache Konvertierung in HTML-Entitäten in einem HTML-Kontext.
Wenn Sie unter Windows arbeiten und cmd.exe verwenden, können Sie
chcp 65001
eingeben, um die Ausgabe von utf-8 zu aktivieren (funktioniert mit der Schriftart Lucida Console). Möglicherweise müssen Sie hinzufügenmyUnicodeString.encode('utf8')
.quelle
Sie haben "" geschrieben. Ich nehme an, das bedeutet, dass der HTML-Code irgendwo einen falsch geformten Unicode-Versuch enthält. ""
Es wird NICHT erwartet, dass der HTML-Code irgendeine Art von "Unicode-Versuch" enthält, ob wohlgeformt oder nicht. Es muss notwendigerweise Unicode-Zeichen enthalten, die in einer Codierung codiert sind, die normalerweise im Voraus bereitgestellt wird. Suchen Sie nach "Zeichensatz".
Sie scheinen anzunehmen, dass der Zeichensatz UTF-8 ist ... aus welchen Gründen? Das in Ihrer Fehlermeldung angezeigte Byte "\ xA0" zeigt an, dass Sie möglicherweise einen Einzelbyte-Zeichensatz haben, z. B. cp1252.
Wenn die Deklaration zu Beginn des HTML- Codes keinen Sinn ergibt , versuchen Sie es mit Chardet herauszufinden, wie wahrscheinlich die Codierung ist.
Warum haben Sie Ihre Frage mit "Regex" markiert?
Aktualisieren Sie, nachdem Sie Ihre gesamte Frage durch eine Nicht-Frage ersetzt haben:
quelle
Wenn Sie eine Zeichenfolge haben
line
, können Sie die.encode([encoding], [errors='strict'])
Methode für Zeichenfolgen verwenden, um Codierungstypen zu konvertieren.line = 'my big string'
line.encode('ascii', 'ignore')
Weitere Informationen zum Umgang mit ASCII und Unicode in Python finden Sie auf dieser wirklich nützlichen Website: https://docs.python.org/2/howto/unicode.html
quelle
Ich denke, die Antwort ist da, aber nur in Teilen, was es schwierig macht, das Problem schnell zu beheben, wie z
Nehmen wir ein Beispiel: Angenommen, ich habe eine Datei mit einigen Daten in der folgenden Form (mit ASCII- und Nicht-ASCII-Zeichen).
10.01.17, 21:36 Uhr - Land: Willkommen ��
und wir wollen nur ASCII-Zeichen ignorieren und beibehalten.
Dieser Code reicht aus:
und geben Sie (rline) ein
quelle
Funktioniert bei mir
quelle
Sieht so aus, als würden Sie Python 2.x verwenden. Python 2.x ist standardmäßig ASCII und kennt Unicode nicht. Daher die Ausnahme.
Fügen Sie einfach die folgende Zeile nach Shebang ein, es wird funktionieren
quelle
coding
Kommentar ist kein magisches Allheilmittel. Sie müssen wissen, warum der Fehler generiert wird. Dies behebt Probleme nur, wenn Ihre Python-Quelle fehlerhafte Zeichen enthält. Dies scheint bei dieser Frage nicht der Fall zu sein.