2011-08-04 16 views
14

Estoy tratando de escribir algunas cadenas en un archivo (las cadenas me han sido dadas por el analizador HTML BeautifulSoup).UnicodeEncodeError al escribir en un archivo

puedo usar "imprimir" para mostrarlos, pero cuando se utiliza file.write() me sale el siguiente error:

UnicodeEncodeError: 'ascii' codec can't encode character u'\xa3' in position 6: ordinal not in range(128) 

¿Cómo puedo analizar esto?

Respuesta

11

Este error se produce cuando pasa una cadena Unicode que contiene caracteres no ingleses (caracteres Unicode más allá de 128) a algo que espera una cadena de bytes ASCII. La codificación predeterminada para una cadena de bytes de Python es ASCII, "que maneja exactamente 128 caracteres (en inglés)". Esta es la razón por la cual intentar convertir caracteres Unicode más allá de 128 produce el error.

El Unicode()

unicode(string[, encoding, errors]) 

constructor tiene el Unicode firma (cadena [, codificación, errores]). Todos sus argumentos deben ser cadenas de 8 bits.

El primer argumento se convierte a Unicode utilizando la codificación especificada; si se deja fuera el argumento de codificación, la codificación ASCII se utiliza para la conversión, por lo que los personajes mayores que 127 serán tratados como errores

por ejemplo

s = u'La Pe\xf1a' 
print s.encode('latin-1') 

o

write(s.encode('latin-1')) 

codificará con latin-1

+0

La cadena está la salida es un precio como "£ 123" – Rory

+0

que no es ASCII válidos. El signo de libra es el código de char 163, fuera del rango ASCII de 127. –

+0

Debe especificar una codificación que pueda codificar esos caracteres. Los archivos no contienen caracteres; ellos contienen bytes. Las codificaciones convierten caracteres en bytes. –

17

Sí, aproximadamente 99,9% o f veteranos usuarios de Python lo han visto antes.

Si escribo 'python unicode' en Google, obtengo unos 14 millones de resultados; el primero es http://docs.python.org/howto/unicode.html el documento oficial que describe toda la situación con detalles insoportables; y el cuarto es http://farmdev.com/talks/unicode/, que es una descripción más práctica que prácticamente le dará una respuesta, y también se asegurará de que entienda lo que está pasando.

Realmente necesita leer y comprender este tipo de panoramas, por mucho tiempo que parezcan. Realmente no hay forma de evitarlo. El texto es difícil. No existe el "texto plano", no ha habido un facsímil razonable durante años, y nunca lo hubo, aunque pasamos décadas fingiendo que existía. Pero Unicode es al menos un estándar.

También debe leer http://www.joelonsoftware.com/articles/Unicode.html.

+0

¡Gracias por los enlaces! Muy útil – tatlar

4

La respuesta a su pregunta es "use codecs". El código adjunto también muestra algo de magia de texto, FWIW. http://wiki.wxpython.org/Internationalization

import codecs 

import gettext 

localedir = './locale' 
langid = wx.LANGUAGE_DEFAULT # use OS default; or use LANGUAGE_JAPANESE, etc. 
domain = "MyApp"    
mylocale = wx.Locale(langid) 
mylocale.AddCatalogLookupPathPrefix(localedir) 
mylocale.AddCatalog(domain) 

translater = gettext.translation(domain, localedir, 
           [mylocale.GetCanonicalName()], fallback = True) 
translater.install(unicode = True) 

# translater.install() installs the gettext _() translater function into our namespace... 

msg = _("A message that gettext will translate, probably putting Unicode in here") 

# use codecs.open() to convert Unicode strings to UTF8 

Logfile = codecs.open(logfile_name, 'w', encoding='utf-8') 

Logfile.write(msg + '\n') 

A pesar de estar lleno Google de los accesos a este problema, me pareció bastante difícil encontrar una solución tan simple (en realidad es en la documentación de Python sobre Unicode, sino más bien enterrado).

Así que ... HTH ...

gaj

+0

"Simple"? Eso también muestra un montón de maquinaria i18n que a OP no le importa: no está tratando de asegurarse de que las personas vean el texto en el idioma correcto, está tratando de tomar el texto en un idioma específico de una fuente específica y ponerlo en un archivo . Entonces, la única parte relevante de su recorte es la primera línea y las dos últimas, realmente. En cuanto a "difícil de encontrar", ¿en serio? ¿Para qué buscabas Google? Intenté 'UnicodeEncodeError: 'ascii' codec no puede codificar el carácter'; los resultados parecen bastante útiles ... –

Cuestiones relacionadas