python import beautifulsoup - UnicodeEncodeError: el codec 'ascii' no puede codificar el carácter u '\ xa0' en la posición 20: ordinal no está dentro del rango (128)





9 Answers

Este es un clásico punto de dolor Python Unicode! Considera lo siguiente:

a = u'bats\u00E0'
print a
 => batsà

Todo bien hasta ahora, pero si llamamos a str (a), veamos qué sucede:

str(a)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeEncodeError: 'ascii' codec can't encode character u'\xe0' in position 4: ordinal not in range(128)

Oh chapuzón, eso no va a hacer ningún bien a nadie! Para corregir el error, codifique los bytes explícitamente con .encode y dígale a python qué códec usar:

a.encode('utf-8')
 => 'bats\xc3\xa0'
print a.encode('utf-8')
 => batsà

Voil \ u00E0!

El problema es que cuando llamas a str (), python usa la codificación de caracteres predeterminada para probar y codificar los bytes que le diste, que en tu caso a veces son representaciones de caracteres Unicode. Para solucionar el problema, debes decirle a Python cómo lidiar con la cadena que le das usando .encode ('whatever_unicode'). La mayoría de las veces, debería estar bien usando utf-8.

Para una excelente exposición sobre este tema, vea la charla de PyCon de Ned Batchelder aquí: http://nedbatchelder.com/text/unipain.html

tutorial decode beautifulsoup4

Tengo problemas para tratar con caracteres Unicode del texto obtenido de diferentes páginas web (en diferentes sitios) Estoy usando BeautifulSoup.

El problema es que el error no siempre es reproducible; a veces funciona con algunas páginas y, a veces, barfs lanzando un UnicodeEncodeError . He intentado casi todo lo que puedo pensar, y sin embargo, no he encontrado nada que funcione de manera coherente sin lanzar algún tipo de error relacionado con Unicode.

A continuación se muestra una de las secciones de código que está causando problemas:

agent_telno = agent.find('div', 'agent_contact_number')
agent_telno = '' if agent_telno is None else agent_telno.contents[0]
p.agent_info = str(agent_contact + ' ' + agent_telno).strip()

Aquí hay un seguimiento de pila producido en ALGUNAS cadenas cuando se ejecuta el fragmento de código anterior:

Traceback (most recent call last):
  File "foobar.py", line 792, in <module>
    p.agent_info = str(agent_contact + ' ' + agent_telno).strip()
UnicodeEncodeError: 'ascii' codec can't encode character u'\xa0' in position 20: ordinal not in range(128)

Sospecho que esto se debe a que algunas páginas (o más específicamente, las páginas de algunos de los sitios) pueden estar codificadas, mientras que otras pueden estar sin codificar. Todos los sitios tienen su sede en el Reino Unido y proporcionan datos destinados al consumo del Reino Unido, por lo que no hay problemas relacionados con la internalización o el tratamiento de textos escritos en otro idioma que no sea el inglés.

¿Alguien tiene alguna idea sobre cómo resolver esto para que así pueda solucionar este problema DE FORMA CONSISTENTE?




Bueno, lo intenté todo, pero no me ayudó. Después de buscar en Google, calculé lo siguiente y me ayudó. Python 2.7 está en uso.

# encoding=utf8
import sys
reload(sys)
sys.setdefaultencoding('utf8')



De hecho, he descubierto que en la mayoría de mis casos, eliminar esos personajes es mucho más simple:

s = mystring.decode('ascii', 'ignore')



Agregue la línea a continuación al comienzo de su script (o como segunda línea):

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

Esa es la definición de la codificación del código fuente de Python. Más información en PEP 263 .




Aquí hay una repetición de algunas de las llamadas respuestas "de salida". Hay situaciones en las que simplemente tirar los molestos caracteres / cuerdas es una buena solución, a pesar de las protestas que se expresan aquí.

def safeStr(obj):
    try: return str(obj)
    except UnicodeEncodeError:
        return obj.encode('ascii', 'ignore').decode('ascii')
    except: return ""

Probandolo

if __name__ == '__main__': 
    print safeStr( 1 ) 
    print safeStr( "test" ) 
    print u'98\xb0'
    print safeStr( u'98\xb0' )

Resultados:

1
test
98°
98

Sugerencia: es posible que desee nombrar esta función como toAscii en toAscii lugar? Esa es una cuestión de preferencia.




Funciones de ayuda simples que se encuentran here .

def safe_unicode(obj, *args):
    """ return the unicode representation of obj """
    try:
        return unicode(obj, *args)
    except UnicodeDecodeError:
        # obj is byte string
        ascii_text = str(obj).encode('string_escape')
        return unicode(ascii_text)

def safe_str(obj):
    """ return the byte string representation of obj """
    try:
        return str(obj)
    except UnicodeEncodeError:
        # obj is unicode
        return unicode(obj).encode('unicode_escape')



Solo agregue a una codificación variable ('utf-8')

agent_contact.encode('utf-8')



Nos encontramos con este error cuando manage.py migrate en Django con dispositivos localizados.

Nuestra fuente contenía la declaración # -*- coding: utf-8 -*- , MySQL se configuró correctamente para utf8 y Ubuntu tenía el paquete de idioma y los valores adecuados en /etc/default/locale .

El problema era simplemente que al contenedor Django (usamos la ventana acoplable) le faltaba la var.

La configuración de LANG en en_US.UTF-8 y el reinicio del contenedor antes de volver a ejecutar las migraciones solucionó el problema.




Acabo de tener este problema y Google me guió aquí, así que solo para agregar a las soluciones generales aquí, esto es lo que funcionó para mí:

# 'value' contains the problematic data
unic = u''
unic += value
value = unic

Tuve esta idea después de leer http://nedbatchelder.com/text/unipain.html .

Sin embargo, no pretendo entender completamente por qué funciona esto. Entonces, si alguien puede editar esta respuesta o hacer un comentario para explicar, se lo agradeceré.




Related