2010-07-11 16 views
86

estoy leyendo y analizar un archivo XML Amazonas y mientras el archivo XML muestra una ", cuando trato de imprimir que me sale el siguiente error:Unicode de Python Codificar error

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

Por lo que he leído en línea hasta ahora, el error proviene del hecho de que el archivo XML está en UTF-8, pero Python quiere manejarlo como un carácter codificado en ASCII. ¿Hay alguna manera sencilla de hacer desaparecer el error y hacer que mi programa imprima el XML tal como se lee?

+0

Estaba llegando a SO para publicar esta pregunta. ¿Hay alguna manera fácil de desinfectar una cadena para 'unicode()'? –

+0

Consulte también [this] (http://stackoverflow.com/questions/3224427/python-sanitize-a-string-for-unicode/3224890#3224890) respuesta a una pregunta relacionada: "Python UnicodeDecodeError - ¿No entiendo mal la codificación? ?” – tzot

Respuesta

163

Probablemente, su problema es que lo analizó correctamente, y ahora está tratando de imprimir el contenido del XML y no puede porque hay algunos caracteres Unicode foráneos. Trate de codificar la cadena Unicode como ASCII primera:

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

la parte 'ignorar' le dirá que acaba de saltar a esos personajes. A partir de la documentación de Python:

>>> 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;' 

Es posible que desee leer este artículo: http://www.joelonsoftware.com/articles/Unicode.html, que me pareció muy útil como un tutorial básico sobre lo que está pasando. Después de la lectura, dejarás de sentir que simplemente estás adivinando qué comandos usar (o al menos eso me pasó a mí).

+1

Estoy tratando de hacer que la siguiente cadena sea segura: 'foo' barra de barra 'df' (nota las comillas rizadas), pero lo anterior aún falla para mí. –

+0

@Rosarch: ¿Cómo funciona? ¿mismo error? ¿Y qué regla de manejo de errores usaste? –

+0

@Rosarch, su problema probablemente sea anterior. Prueba este código: # - * - coding: latino-1 - * - u = u 'foo ‘barra de bar’ df' u.encode print ('ascii', 'ignorar') Para usted, probablemente estaba convirtiendo su cadena en unicode dada la codificación que especificó para el scrip de python que arrojó el error. –

0

se puede usar algo de la forma

s.decode('utf-8') 

que convertirá una codificación UTF-8 cadena de bytes en una cadena Unicode de Python. Pero el procedimiento exacto a usar depende exactamente de cómo cargue y analice el archivo XML, p. si nunca accedes directamente a la cadena XML, es posible que debas utilizar un objeto decodificador del codecs module.

+0

ya está codificado en UTF-8 el error es específicamente: myStrings = deque ([u'Dorf y Svoboda \ u2019s texto se basa en el str ... Ingeniería Informática y \ u2019s subdisciplinas '.]) el la cadena está en UTF-8 como puede ver, pero se enoja con el interno '\ u2019' –

+0

Oh, bien, pensé que estaba teniendo un problema diferente. –

+7

@Alex B: No, la cadena es Unicode, no Utf-8. Para ** codificar ** como Utf-8 use ''...' codificar ('utf-8')' – sth

13

Una solución mejor:

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) 

Si desea leer más sobre por qué:

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

+3

No ayuda con el problema de OP: * "no se puede codificar el carácter u '\ u2019'" *. 'u '\ u2019' ya es Unicode. – jfs

3

No codificar la codificación de caracteres de su entorno dentro del guión; imprimir texto Unicode directamente en su lugar:

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

Si su salida se redirige a un archivo (o una tubería); usted podría utilizar PYTHONIOENCODING varentorno, para especificar la codificación de caracteres:

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

De lo contrario, python your_script.py debería funcionar tal cual - los valores de localización se utilizan para codificar el texto (en el cheque POSIX: LC_ALL, LC_CTYPE, LANG envvars - establezca LANG en una configuración regional utf-8 si es necesario).

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

0

Escribí lo siguiente para corregir las molestas citas no originales y forzar la conversión a algo utilizable.

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

Pruebe agregar la siguiente línea en la parte superior de su secuencia de comandos python.

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

La sintaxis correcta es: '# - * - codificación: utf-8 - * -' – azuax

1

Excelente mensaje: 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

Si necesita imprimir una representación aproximada de la cadena a la pantalla, en lugar de ignorar esos caracteres no imprimibles, por favor intente unidecode paquete aquí:

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

La explicación se encuentra aquí:

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

Esto es mejor que usar el u.encode('ascii', 'ignore') para una cadena dada u, y puede ahorrarse de dolor de cabeza innecesario si la precisión personaje no es lo que está después, pero todavía quiere tener la legibilidad humana.

Wirawan

Cuestiones relacionadas