Python ElementTree konvertiert nicht schussfreie Leerzeichen nicht, wenn UTF-8 für die Ausgabe verwendet wird

9

Ich versuche, HTML zu analysieren, zu manipulieren und mit Pythons ElementTree auszugeben:

%Vor%

Wenn ich dies mit Python 2.7 unter Mac OS X 10.6 ausführe, bekomme ich:

%Vor%

Ich dachte, dass die Angabe von "encoding = 'UTF-8'" sich um das nicht-brechende Leerzeichen kümmern würde, aber anscheinend nicht. Was sollte ich stattdessen tun?

    
Greg Wilson 18.05.2012, 13:40
quelle

5 Antworten

6

0xA0 ist ein latin1-Zeichen, kein Unicode-Zeichen und der Wert von p.text in der Schleife ist ein str und kein Unicode, dh um es in utf-8 zu codieren, muss es zuerst implizit von Python konvertiert werden in eine Unicode-Zeichenfolge (dh mit Dekodierung). Wenn es dies tut, nimmt es Ascii an, da es nichts anderes gesagt hat. 0xa0 ist kein gültiges ASCII-Zeichen, aber es ist ein gültiges latin1-Zeichen.

Der Grund, warum Sie latin1-Zeichen anstelle von Unicode-Zeichen haben, liegt daran, dass es sich bei entitydefs um eine Zuordnung von Namen zu latin1-encode-Zeichenfolgen handelt. Sie benötigen den Unicode-Codepunkt, den Sie von htmlentitydef.name2codepoint

erhalten können

Die folgende Version sollte es für Sie beheben:

%Vor%     
lambacck 29.05.2012 02:37
quelle
4

XML definiert nur < , > , ' , " und & .   und andere stammen aus HTML. Sie haben also eine Auswahl.

  1. Sie können Ihre Quelle ändern, um numerische Entitäten zu verwenden, wie   oder   , die beide mit   identisch sind.
  2. Sie können eine DTD verwenden, die diese Werte definiert.

Es gibt einige nützliche Informationen (es wird über XSLT geschrieben, aber XSLT wird unter Verwendung von XML geschrieben, also gilt das Gleiche) im XSLT FAQ .

Die Frage erscheint jetzt, um eine Stack-Trace zu enthalten; Das ändert die Dinge. Sind Sie sicher, dass die Zeichenfolge in UTF-8 ist? Wenn es in das einzelne Byte 0xA0 aufgelöst wird, dann ist es nicht UTF-8 , sondern eher cp1252 oder iso-8859-1 .

    
lavinio 18.05.2012 13:54
quelle
3

Ihre   wird in '\ xa0' konvertiert, was die Standardcodierung (ascii) für ein nichtbrechendes Leerzeichen ist (die UTF-8-Codierung ist '\ xc2 \ xa0'). Die Zeile

%Vor%

führt zu einem UnicodeDecodeError, weil der Standard-Codec ascii nur bis zu 128 Zeichen und ord ('\ xa0') = 160 verwendet. Die Standardcodierung auf etwas anderes setzen, d. h .:

%Vor%

sollte dein Problem lösen.

    
Ben Morris 29.05.2012 03:37
quelle
-1

HTML ist nicht dasselbe wie XML, also werden Tags wie   nicht funktionieren. Idealerweise könnten Sie, wenn Sie versuchen, diese Informationen über XML zu übergeben, zuerst die obigen Daten xml-codieren, so dass es etwa so aussieht:

%Vor%

Und dann nach dem Parsen der XML können Sie die Zeichenfolge HTML-unencode.

    
chaimp 18.05.2012 14:09
quelle
-1

Ich denke, das Problem, das Sie hier haben, liegt nicht in Ihrer nbsp-Entität, sondern in Ihrer print-Anweisung.

Ihr Fehler ist:

  

UnicodeDecodeError: 'ascii' Codec kann das Byte 0xa0 in Position 19 nicht dekodieren: Ordinal nicht im Bereich (128)

Ich denke, das liegt daran, dass Sie eine utf-8-Zeichenfolge (aus ET.tostring(p, encoding='utf-8') ) verwenden und versuchen, sie in einem ASCII-Terminal auszuhacken. Also konvertiert Python diese Zeichenfolge implizit in Unicode und konvertiert sie dann wieder in ASCII. Obwohl nbsp kann direkt in utf-8 dargestellt werden, kann nicht direkt in ascii dargestellt werden. Daher der Fehler.

Versuchen Sie, die Ausgabe stattdessen in einer Datei zu speichern und zu sehen, ob Sie das bekommen, was Sie erwarten.

Alternativ können Sie print ET.toString(p, encoding='ascii') verwenden, was dazu führen sollte, dass ElementTree numerische Zeichenentitäten verwendet, um etwas darzustellen, das nicht mit ASCII dargestellt werden kann.

    
Francis Avila 18.05.2012 15:05
quelle

Tags und Links