UnicodeEncodeError: el códec 'ascii' no puede codificar el carácter u'\xa0' en la posición 20: el ordinal no está en el rango (128)

Resuelto Homunculus Reticulli asked hace 12 años • 34 respuestas

Tengo problemas para tratar con caracteres Unicode de 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, vomita lanzando un archivo UnicodeEncodeError. He probado casi todo lo que se me ocurre y, aún así, no he encontrado nada que funcione de manera consistente sin generar algún tipo de error relacionado con Unicode.

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

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 la pila producido en ALGUNAS cadenas cuando se ejecuta el fragmento 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, páginas de algunos de los sitios) pueden estar codificadas, mientras que otras pueden no estar codificadas. Todos los sitios tienen su sede en el Reino Unido y proporcionan datos destinados al consumo en el Reino Unido, por lo que no hay problemas relacionados con la internalización o el manejo de texto escrito en otro idioma que no sea inglés.

¿Alguien tiene alguna idea sobre cómo resolver esto para poder solucionar este problema CONSISTENTE?

Homunculus Reticulli avatar Mar 30 '12 19:03 Homunculus Reticulli
Aceptado

Lea el CÓMO de Python Unicode . Este error es el primer ejemplo .

No lo utilice str()para convertir de Unicode a texto/bytes codificados.

En su lugar, utilice .encode()para codificar la cadena:

p.agent_info = u' '.join((agent_contact, agent_telno)).encode('utf-8').strip()

o trabajar completamente en Unicode.

agf avatar Mar 30 '2012 12:03 agf

¡Este es un punto débil clásico de Python Unicode! Considera lo siguiente:

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

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

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, idiota, eso no le hará 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à

¡Vaya\u00E0!

El problema es que cuando llamas a str(), Python usa la codificación de caracteres predeterminada para intentar codificar los bytes que le asignaste, que en tu caso a veces son representaciones de caracteres Unicode. Para solucionar el problema, debe decirle a Python cómo manejar la cadena que le proporciona usando .encode('whatever_unicode'). La mayoría de las veces, deberías estar bien usando utf-8.

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

Andbdrew avatar Mar 30 '2012 12:03 Andbdrew

Encontré una solución elegante para eliminar símbolos y continuar manteniendo la cadena como cadena de la siguiente manera:

yourstring = yourstring.encode('ascii', 'ignore').decode('ascii')

Es importante tener en cuenta que usar la opción ignorar es peligroso porque elimina silenciosamente cualquier soporte Unicode (e internacionalización) del código que la usa, como se ve aquí (convertir Unicode):

>>> u'City: Malmö'.encode('ascii', 'ignore').decode('ascii')
'City: Malm'
Max Korolevsky avatar Aug 20 '2014 10:08 Max Korolevsky

Bueno, intenté todo pero no ayudó, después de buscar en Google descubrí lo siguiente y ayudó. Python 2.7 está en uso.

# encoding=utf8
import sys
reload(sys)
sys.setdefaultencoding('utf8')
Ashwin avatar Sep 02 '2016 13:09 Ashwin