2010-07-11 22 views
86

sto leggendo e l'analisi di un file XML Amazon e mentre il file XML mostra un ', quando provo a stamparlo ottengo il seguente errore:Python Unicode Codifica errore

'ascii' codec can't encode character u'\u2019' in position 16: ordinal not in range(128) 

Da quello che ho letto online fino ad ora, l'errore deriva dal fatto che il file XML è in UTF-8, ma Python vuole gestirlo come un carattere codificato ASCII. C'è un modo semplice per far sparire l'errore e fare in modo che il mio programma stampi l'XML mentre legge?

+0

Stavo solo venendo a SO per pubblicare questa domanda. C'è un modo semplice per disinfettare una stringa per 'unicode()'? –

+0

Controlla anche [this] (http://stackoverflow.com/questions/3224427/python-sanitize-a-string-for-unicode/3224890#3224890) rispondi a una domanda correlata: "Python UnicodeDecodeError - Mi capita di non capire ?” – tzot

risposta

163

Probabilmente il problema è che l'hai analizzato bene, e ora stai provando a stampare il contenuto dell'XML e non puoi perché ci sono alcuni caratteri Unicode stranieri. Provare per codificare la stringa Unicode come ASCII prima:

unicodeData.encode('ascii', 'ignore') 

la parte 'ignorare' lo dirà di saltare quei personaggi. Dalla documentazione pitone:

>>> u = unichr(40960) + u'abcd' + unichr(1972) 
>>> u.encode('utf-8') 
'\xea\x80\x80abcd\xde\xb4' 
>>> u.encode('ascii') 
Traceback (most recent call last): 
    File "<stdin>", line 1, in ? 
UnicodeEncodeError: 'ascii' codec can't encode character '\ua000' in position 0: ordinal not in range(128) 
>>> u.encode('ascii', 'ignore') 
'abcd' 
>>> u.encode('ascii', 'replace') 
'?abcd?' 
>>> u.encode('ascii', 'xmlcharrefreplace') 
'&#40960;abcd&#1972;' 

Si potrebbe desiderare di leggere questo articolo: http://www.joelonsoftware.com/articles/Unicode.html, che ho trovato molto utile come un tutorial di base su quello che sta succedendo. Dopo la lettura, smetterai di sentire che stai solo indovinando quali comandi usare (o almeno quello che è successo a me).

+1

Sto provando a rendere sicura la seguente stringa: 'foo' bar bar "df '(nota le virgolette ricci), ma quanto sopra non ha ancora successo per me. –

+0

@Rosarch: errore come? stesso errore? E quale regola di gestione degli errori hai usato? –

+0

@Rosarch, il tuo problema è probabilmente precedente. Prova di questo codice: # - * - codifica: latin-1 - * - u = u 'foo ‘bar bar’ df' stampa u.encode ('ascii', 'ignorare') Per voi, probabilmente stava convertendo la tua stringa INTO in unicode data la codifica che hai specificato per lo script python che ha generato l'errore. –

0

è possibile utilizzare qualcosa della forma

s.decode('utf-8') 

che convertirà una codifica UTF-8 bytestring in una stringa Python Unicode. Ma la procedura esatta da utilizzare dipende esattamente da come si carica e analizza il file XML, ad es. se non si accede direttamente alla stringa XML, potrebbe essere necessario utilizzare un oggetto decoder da codecs module.

+0

e 'già codificato in UTF-8 l'errore è specifico: myStrings = coda doppia ([u'Dorf e Svoboda \ u2019s testo si basa sulla str ... e Ingegneria Informatica \ u2019s sottodiscipline'.]) il la stringa è in UTF-8, come potete vedere, ma si arrabbia con l'interno '\ u2019' –

+0

Oh, OK, pensavo che aveste un altro problema. –

+7

@Alex B: No, la stringa è Unicode, non Utf-8. Per ** codificare ** come Utf-8 usa ''...'. Encode ('utf-8')' – sth

13

Una soluzione migliore:

if type(value) == str: 
    # Ignore errors even if the string is not proper UTF-8 or has 
    # broken marker bytes. 
    # Python built-in function unicode() can do this. 
    value = unicode(value, "utf-8", errors="ignore") 
else: 
    # Assume the value object has proper __unicode__() method 
    value = unicode(value) 

Se volete saperne di più sul perché:

http://docs.plone.org/manage/troubleshooting/unicode.html#id1

+3

Non aiuta con il problema dell'OP: * "non può codificare il carattere u '\ u2019'" *. 'u '\ u2019' è già Unicode. – jfs

3

Non hardcode la codifica dei caratteri del vostro ambiente all'interno dello script; stampare direttamente il testo Unicode:

assert isinstance(text, unicode) # or str on Python 3 
print(text) 

Se l'output viene reindirizzato a un file (o una pipe); si potrebbe usare PYTHONIOENCODING envvar, per specificare la codifica dei caratteri:

$ PYTHONIOENCODING=utf-8 python your_script.py >output.utf8 

In caso contrario, python your_script.py dovrebbe funzionare così com'è - impostazioni locali vengono utilizzate per codificare il testo (al momento del check POSIX: LC_ALL, LC_CTYPE, LANG envvars - impostare LANG in una locale utf-8, se necessario).

To print Unicode on Windows, see this answer that shows how to print Unicode to Windows console, to a file, or using IDLE.

0

Ho scritto quanto segue per correggere le citazioni non-ascii fastidiose e forzare la conversione in qualcosa di utile.

unicodeToAsciiMap = {u'\u2019':"'", u'\u2018':"`", } 

def unicodeToAscii(inStr): 
    try: 
     return str(inStr) 
    except: 
     pass 
    outStr = "" 
    for i in inStr: 
     try: 
      outStr = outStr + str(i) 
     except: 
      if unicodeToAsciiMap.has_key(i): 
       outStr = outStr + unicodeToAsciiMap[i] 
      else: 
       try: 
        print "unicodeToAscii: add to map:", i, repr(i), "(encoded as _)" 
       except: 
        print "unicodeToAscii: unknown code (encoded as _)", repr(i) 
       outStr = outStr + "_" 
    return outStr 
0

Prova ad aggiungere la seguente riga nella parte superiore del tuo script python.

# _*_ coding:utf-8 _*_ 
+0

La sintassi corretta è: '# - * - codifica: utf-8 - * -' – azuax

1

Ottimo post: http://www.carlosble.com/2010/12/understanding-python-and-unicode/

# -*- coding: utf-8 -*- 

def __if_number_get_string(number): 
    converted_str = number 
    if isinstance(number, int) or \ 
      isinstance(number, float): 
     converted_str = str(number) 
    return converted_str 


def get_unicode(strOrUnicode, encoding='utf-8'): 
    strOrUnicode = __if_number_get_string(strOrUnicode) 
    if isinstance(strOrUnicode, unicode): 
     return strOrUnicode 
    return unicode(strOrUnicode, encoding, errors='ignore') 


def get_string(strOrUnicode, encoding='utf-8'): 
    strOrUnicode = __if_number_get_string(strOrUnicode) 
    if isinstance(strOrUnicode, unicode): 
     return strOrUnicode.encode(encoding) 
    return strOrUnicode 
0

Se avete bisogno di stampare una rappresentazione approssimativa della stringa sullo schermo, piuttosto che ignorare quei caratteri non stampabili, riprova unidecode pacchetto qui:

https://pypi.python.org/pypi/Unidecode

La spiegazione si trova qui:

https://www.tablix.org/~avian/blog/archives/2009/01/unicode_transliteration_in_python/

Questo è meglio che utilizzare il u.encode('ascii', 'ignore') per una data stringa u, e si può salvare da mal di testa inutili se la precisione personaggio non è che cosa siete dopo, ma ancora voglia di avere la leggibilità umana.

Wirawan

Problemi correlati