Codifica dà “’ascii’ codec riesco a codificare il carattere … ordinale non in range(128)”

Sto lavorando attraverso il Django lettore RSS progetto qui.

I feed RSS di leggere qualcosa del tipo “OKLAHOMA CITY (AP) — James Harden lasciare”. Il feed RSS di codifica legge encoding=”UTF-8″ quindi credo che sto passando utf-8 di markdown, nel frammento di codice riportato di seguito. La lineetta è dove lo soffoca.

Ho il Django di errore di “‘ascii’ codec riesco a codificare il carattere u’\u2014′ in posizione 109: ordinale non in range(128)”, che è un UnicodeEncodeError. Nel passaggio di variabili vedo “OKLAHOMA CITY (AP) \u2014 James Harden”. La linea di codice che non funziona è:

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

Sto usando markdown 2.0, django 1.1, e python 2.4.

Che cosa è la magia sequenza di codifica e decodifica che devo fare per fare questo lavoro?


(In risposta a Prometeo’ richiesta. Sono d’accordo con l’formattazione aiuta)

Così in vista, aggiungo un smart_unicode linea sopra il parsed_feed codifica di linea…

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

Questo spinge il problema a mio models.py per me, dove ho

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

Se cambio il metodo di salvataggio per avere…

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)

Ottengo l’errore “‘ascii’ codec non può decodificare byte 0xe2 in posizione 141: ordinale non in range(128)” perché ora è legge “\xe2\x80\x94” dove la lineetta era

  • potrebbe per favore postare il traceback così com’è?
  • In sostanza, qual è il valore di parsed_feed.encoding? È ‘ascii’, per caso? (che spiegherebbe sia la vostra errori).
InformationsquelleAutor user140314 | 2010-03-25

 

3 Replies
  1. 12

    Se i dati che si ricevono, infatti, è codificato in UTF-8, quindi dovrebbe essere una sequenza di byte — Python ‘str’ oggetto, in Python 2.X

    È possibile verificare questo con un’affermazione:

    assert isinstance(content, str)

    Una volta che sai che è vero, è possibile spostare la codifica reale. Python non fare la transcodifica — direttamente da UTF-8 a ASCII, per esempio. È necessario attivare prima la sequenza di byte in una stringa Unicode, dalla decodifica:

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

    (Se ci si può fidare parsed_feed.la codifica, quindi utilizzare al posto di quella letterale ‘utf-8’. In ogni modo, essere preparati per gli errori.)

    Quindi, si può prendere la stringa, e la codifica in ASCII, sostituendo alta personaggi con i loro entità XML equivalenti:

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

    Il metodo completo, quindi, sarebbe qualcosa di simile a questo:

    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
  2. 4

    Django fornisce un paio di utili funzioni per la conversione di avanti e indietro tra Unicode e bytestrings:

    da django.utils.codifica di importazione smart_unicode, smart_str

    • Utilizzando… content = smart_unicode(contenuto, encoding=’utf-8′, strings_only=False, errori=’stretto’) contenuto = contenuto = contenuto.codificare(parsed_feed.codifica”, xmlcharrefreplace”) spinge il problema a mio models.py per me, dove ho def salvare(self, force_insert=False, force_update=False): se stesso.estratto: self.excerpt_html = markdown(self.excerpt) # super save dopo questo Se cambio il metodo di salvataggio per avere encoded_excerpt_html = (self.estratto).encode(‘utf-8’) self.excerpt_html = markdown(encoded_excerpt_html)
    • Parte 2: ricevo l’errore “‘ascii’ codec non può decodificare byte 0xe2 in posizione 141: ordinale non in range(128)” perché ora è legge “\xe2\x80\x94” dove la lineetta era.
    • Potresti per favore modificare il tuo post originale, con la sopra? E ‘ molto difficile da leggere senza formattazione corretta.
    • tu sei il salvatore!
    • Grazie smart_unicode è grande !!
  3. 0

    Ho trovato questo errore durante la scrittura di un nome di file con estensione zip. La seguente non è riuscito

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

    e seguenti lavorato

    ZipFile.write(str(root+'/%s'%file), str(newRoot + '/%s'%file))
    • Chiamata str() su un valore unicode con caratteri non-ASCII risultato sarebbe lo stesso errore l’OP sta vedendo.
    • Ciao, il che è un punto molto importante che si fanno. Non riesco a trovare alcun riferimento a ciò che str() è in realtà facendo in il manuale tuttavia ritengo che per me che sono un Pitone noob più di un errore del manuale. Dove questo documentato, che cosa è esattamente str() facendo per l’argomento, e che cosa fa esattamente str() ritorno? Grazie!
    • str() restituisce un stringa di byte; caratteri con valori tra 0 e 255, con 0-127 di solito interpretati e visualizzati come caratteri ASCII. Un unicode() valore, d’altra parte, può rappresentare qualsiasi codepoint in Unicode standard, tra 0 e 1114111. Quindi, utilizzando str(unicodevalue) a girare unicode in una stringa di byte sta andando a coinvolgere alcuni trasformazione.
    • Il unicode tipo è implementato in C, ma fornisce l’API C equivalente del __str__ gancio per rendere la trasformazione, la realizzazione chiama PyUnicode_AsEncodedString(), e che questa funzione utilizza PyUnicode_GetDefaultEncoding(); indovinate cosa che funzione, non. 🙂
    • Dal momento che non è possibile passare a una codifica a str(), Python non hanno una scelta, ma per utilizzare la codifica predefinita. Quindi è sempre molto meglio per codificare in modo esplicito di una stringa di byte, quando quest’ultimo è necessario. Non utilizzare str(unicodevalue); raramente è una buona idea.

Lascia un commento