2010-03-25 6 views
14

Ich arbeite durch die Django RSS-Reader-Projekt here.Codierung gibt "Ascii" Codec kann nicht codieren ... Ordinal nicht im Bereich (128) "

Der RSS-Feed wird etwas wie "OKLAHOMA CITY (AP) - James Harden lassen" lesen. Die Kodierung des RSS-Feeds lautet encoding = "UTF-8", daher glaube ich, dass ich utf-8 im unten stehenden Code-Snippet übergebe. Der em Strich ist, wo er würgt.

Ich bekomme den Django-Fehler von "Ascii 'Codec kann nicht codieren Zeichen u' \ u2014 'in Position 109: Ordnungszahl nicht im Bereich (128)" was ist ein UnicodeEncodeError. In den Variablen, die übergeben werden, sehe ich "OKLAHOMA CITY (AP) \ u2014 James Harden". Die Codezeile, die nicht funktioniert ist:

content = content.encode(parsed_feed.encoding, "xmlcharrefreplace") 

Ich verwende Abschlag 2.0, django 1.1 und Python 2.4.

Was ist die magische Sequenz von Kodierung und Dekodierung, die ich tun muss, damit dies funktioniert?


(Als Reaktion auf Prometheus' Anfrage. Ich bin damit einverstanden hilft die Formatierung)

So in Aussicht ich eine smart_unicode Zeile oberhalb der parsed_feed Codierung Zeile hinzufügen ...

content = smart_unicode(content, encoding='utf-8', strings_only=False, errors='strict') 
content = content = content.encode(parsed_feed.encoding, "xmlcharrefreplace") 

Dies drückt das problem zu meinem models.py für mich wo ich habe

def save(self, force_insert=False, force_update=False): 
    if self.excerpt: 
     self.excerpt_html = markdown(self.excerpt) 
     # super save after this 

Wenn ich die save-methode zu ändern habe. ..

def save(self, force_insert=False, force_update=False): 
    if self.excerpt: 
     encoded_excerpt_html = (self.excerpt).encode('utf-8') 
     self.excerpt_html = markdown(encoded_excerpt_html) 

ich den Fehler bekommen: es liest " 'ascii' Codec 0xE2 in Position 141 dekodieren kann nicht Byte ordinal nicht in Reichweite (128)" weil jetzt "\ XE2 \ x80 \ x94" wo der em Strich war

+0

könnten Sie bitte die Zurückverfolgungs schreiben, wie sie ist? – tzot

+0

Was ist der Wert von 'parsed_feed.encoding'? Ist es "ascii", per Zufall? (das würde beide Fehler erklären). – tzot

Antwort

4
+1

Mit ... content = smart_unicode (Inhalt, encoding = 'utf-8', strings_only = False, 'strenge' Fehler =) content = Inhalt = content.encode (parsed_feed.encoding "xmlcharrefreplace") Schübe das problem zu meinem models.py für mich wo ich habe def speichern (selbst, force_insert = False, force_update = False): wenn selb.excerpt: selb.excerpt_html = markdown (self.excerpt) # super speichern danach Wenn ich die Speichermethode ändern 2 encoded_excerpt_html = (self.excerpt) .encode ('utf-8') self.excerpt_html = Abschlags (encoded_excerpt_html) – user140314

+0

Teil haben: ich erhalte die Fehlermeldung „ 'ascii' Codec kann Byte 0xe2 an Position 141 nicht dekodieren: Ordnungszahl nicht im Bereich (128) "weil es jetzt" \ xe2 \ x80 \ x94 "lautet, wo der em-Strich war. – user140314

+0

Könnten Sie bitte Ihren ursprünglichen Beitrag mit dem oben genannten ändern? Es ist sehr schwierig, ohne korrekte Formatierung zu lesen. – nikola

12

Wenn die Daten, die Sie erhalten, tatsächlich in UTF-8 kodiert sind, dann sollte es eine Folge von Bytes sein - ein Python 'str' Objekt, in Python 2.X

Sie können dies überprüfen mit eine Behauptung:

assert isinstance(content, str) 

Sobald Sie wissen, dass das wahr ist, können Sie auf die tatsächliche Codierung bewegen. Python führt keine Transcodierung durch - direkt von UTF-8 nach ASCII. Sie müssen zuerst die Sequenz von Bytes in einen Unicode-String drehen, indem sie sie Decodierung:

unicode_content = content.decode('utf-8') 

(Wenn Sie parsed_feed.encoding vertrauen kann, dann, dass anstelle des wörtlichen ‚utf-8‘ oder so. auf Fehler vorbereitet sein.)

kann

Sie nehmen dann die Zeichenfolge, und kodieren sie in ASCII, hohe Charaktere mit ihren XML-Entity-Äquivalente ersetzt:

xml_content = unicode_content.encode('ascii', 'xmlcharrefreplace') 

Die vollständige Methode, dann, somthing würde wie folgt aussehen:

try: 
    content = content.decode(parsed_feed.encoding).encode('ascii', 'xmlcharrefreplace') 
except UnicodeDecodeError: 
    # Couldn't decode the incoming string -- possibly not encoded in utf-8 
    # Do something here to report the error 
0

Ich habe diesen Fehler beim Schreiben eines Dateinamens mit ZIP-Datei festgestellt. Die nach gescheiterter

ZipFile.write(root+'/%s'%file, newRoot + '/%s'%file) 

und die folgende arbeitete

ZipFile.write(str(root+'/%s'%file), str(newRoot + '/%s'%file)) 
+3

Das Aufrufen von 'str()' auf einem Unicode-Wert mit Nicht-ASCII-Zeichen würde genau denselben Fehler zur Folge haben, den das OP sieht. –

+0

@MartijnPieters: Hi, das ist ein sehr wichtiger Punkt, den Sie machen. Ich kann keinen Hinweis darauf finden, was 'str()' in [dem guten Handbuch] (http://docs.python.org/2/library/functions.html#str) tatsächlich tut, aber ich schreibe das zu mir, der ein ist Python noob mehr als ein Fehler des Handbuchs. Wo ist das dokumentiert, was genau macht 'str()' mit dem Argument, und was genau kehrt 'str()' zurück? Vielen Dank! – dotancohen

+0

'str()' gibt eine * Byte-Zeichenfolge * zurück; Zeichen mit Werten zwischen 0 und 255, wobei 0-127 normalerweise als ASCII-Zeichen interpretiert und angezeigt werden. Ein 'unicode()' -Wert kann andererseits einen beliebigen Codepunkt im Unicode-Standard zwischen 0 und 1114111 darstellen. Wenn also 'str (unicodevalue) 'verwendet wird, um Unicode in eine Byte-Zeichenkette umzuwandeln, wird * einige * Transformation benötigt . –