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, irrita lanzando a UnicodeEncodeError
. He intentado casi todo lo que se me ocurre y, sin embargo, no he encontrado nada que funcione de manera consistente sin arrojar 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 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 estar sin codificar. Todos los sitios están ubicados 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 inglés.
¿Alguien tiene alguna idea sobre cómo resolver esto para que pueda solucionar este problema de manera CONSISTENTE?
fuente
import os; import locale; os.environ["PYTHONIOENCODING"] = "utf-8"; myLocale=locale.setlocale(category=locale.LC_ALL, locale="en_GB.UTF-8"); ... print(myText.encode('utf-8', errors='ignore'))
.$ export PYTHONIOENCODING=utf8
Respuestas:
Debe leer el CÓMO de Python Unicode . Este error es el primer ejemplo .
Básicamente, deje de usar
str
para convertir unicode a texto / bytes codificados.En su lugar, use adecuadamente
.encode()
para codificar la cadena:o trabajar completamente en unicode.
fuente
print
mis cadenas utf-8 funciona muy bien. Sin embargo, cuando canalizo la salida de mis programas a un archivo, arroja unUnicodeEncodeError
. De hecho, cuando se redirige la salida (en un archivo o una tubería), me parece quesys.stdout.encoding
esNone
! La tachuela.encode('utf-8')
resuelve el problema.PYTHONIOENCODING=utf-8
en su lugar, es decir, imprima cadenas Unicode y deje que el entorno establezca la codificación esperada..encode()
método para llamar.¡Este es un clásico punto de dolor de Python Unicode! Considera lo siguiente:
Todo bien hasta ahora, pero si llamamos str (a), veamos qué sucede:
¡Oh, chapuzón, 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:
Voil \ u00E0!
El problema es que cuando llamas a str (), python usa la codificación de caracteres predeterminada para intentar codificar los bytes que le diste, 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 da usando .encode ('whatever_unicode'). La mayoría de las veces, debería estar bien con utf-8.
Para una excelente exposición sobre este tema, vea la charla PyCon de Ned Batchelder aquí: http://nedbatchelder.com/text/unipain.html
fuente
None
valor.Encontré una solución elegante para mí para eliminar símbolos y continuar manteniendo la cadena como cadena de la siguiente manera:
Es importante notar que usar la opción de ignorar es peligroso porque silenciosamente elimina cualquier soporte unicode (e internacionalización) del código que lo usa, como se ve aquí (convertir unicode):
fuente
yourstring = yourstring.encode('utf-8', 'ignore').decode('utf-8')
os.path.join()
, es un muy buen hábito cuando comienzas a hacer programación multiplataforma. :)bueno, intenté todo pero no me ayudó, después de buscar en Google pensé lo siguiente y me ayudó. Python 2.7 está en uso.
fuente
if sys.version_info.major < 3:
Un problema sutil que hace que incluso la impresión falle es tener las variables de entorno configuradas incorrectamente, por ejemplo. aquí LC_ALL establecido en "C". En Debian desaconsejan configurarlo: Debian wiki on Locale
fuente
env|grep -E '(LC|LANG)'
.mc
en "modo de subcapa" (Ctrl-O
) y también olvidé que añadido los siguientes alias a bash:alias mc="LANG=en_EN.UTF-8 mc"
. Entonces, cuando traté de ejecutar scripts mal escritos que dependenru_RU.UTF-8
internamente, simplemente mueren. Intenté muchas cosas de este hilo antes de descubrir el verdadero problema. :)Para mí, lo que funcionó fue:
Espero que esto ayude a alguien.
fuente
De hecho, he descubierto que en la mayoría de mis casos, simplemente quitar esos caracteres es mucho más simple:
fuente
El problema es que está intentando imprimir un carácter unicode, pero su terminal no lo admite.
Puede intentar instalar el
language-pack-en
paquete para arreglar eso:que proporciona actualizaciones de datos de traducción al inglés para todos los paquetes compatibles (incluido Python). Instale un paquete de idioma diferente si es necesario (dependiendo de los caracteres que está intentando imprimir).
En algunas distribuciones de Linux es necesario para asegurarse de que las configuraciones regionales inglesas predeterminadas estén configuradas correctamente (para que shell / terminal pueda manejar los caracteres unicode). A veces es más fácil instalarlo que configurarlo manualmente.
Luego, al escribir el código, asegúrese de usar la codificación correcta en su código.
Por ejemplo:
Si todavía tiene un problema, verifique la configuración de su sistema, como:
Su archivo de configuración regional (
/etc/default/locale
), que debería tener p. Ej.o:
Valor de
LANG
/LC_CTYPE
en shell.Compruebe qué configuración regional admite su shell:
Demostrando el problema y la solución en VM nueva.
Inicialice y aprovisione la VM (por ejemplo, usando
vagrant
):Ver: cuadros de Ubuntu disponibles . .
Impresión de caracteres unicode (como el signo de marca como
™
):Ahora instalando
language-pack-en
:Ahora el problema debe resolverse:
De lo contrario, intente el siguiente comando:
fuente
language-pack-en
que ver con Python o esta pregunta? AFAIK, puede proporcionar traducciones de idiomas a los mensajes, pero no tiene nada que ver con la codificación/etc/locale.gen
para asegurarse de que su configuración regional esté construida antes de usarla?LANG
desde/etc/default/locale
(como/etc/locale.gen
existe) y se ejecutólocale-gen
, pero no ayudó. No estoy seguro de quélanguage-pack-en
hace exactamente, ya que no encontré mucha documentación y enumerar el contenido no ayuda mucho.LANG
/LC_CTYPE
/ en suLC_ALL
lugar (por ejemplo,LANG=C.UTF-8
).Con cáscara:
Busque la configuración regional UTF-8 compatible con el siguiente comando:
Exportarlo, antes de ejecutar el script, por ejemplo:
o manualmente como:
Pruébelo imprimiendo caracteres especiales, por ejemplo
™
:Probado anteriormente en Ubuntu.
fuente
Agregue la siguiente línea al comienzo de su secuencia de comandos (o como segunda línea):
Esa es la definición de la codificación del código fuente de Python. Más información en PEP 263 .
fuente
Aquí hay una repetición de algunas de las llamadas respuestas de "cop out". Hay situaciones en las que simplemente tirar los caracteres / cadenas problemáticos es una buena solución, a pesar de las protestas expresadas aquí.
Probándolo:
Resultados:
Sugerencia: ¿es posible que desee nombrar esta función en su
toAscii
lugar? Eso es una cuestión de preferencia.Esto fue escrito para Python 2. Para Python 3, creo que querrá usar en
bytes(obj,"ascii")
lugar destr(obj)
. Todavía no probé esto, pero lo haré en algún momento y revisaré la respuesta.fuente
Siempre pongo el siguiente código en las dos primeras líneas de los archivos de Python:
fuente
Funciones auxiliares simples que se encuentran aquí .
fuente
backslashreplace
gestor de errores:u'\xa0'.encode('ascii', 'backslashreplace')
. Aunque debe evitar dicha representación y configurar su entorno para aceptar caracteres que no sean ascii, ¡es 2016!Simplemente agregue a una codificación variable ('utf-8')
fuente
Abra la terminal y active el siguiente comando:
fuente
Acabo de usar lo siguiente:
Compruebe lo que dice la documentación al respecto:
Lo resuelve por mi. Simple y fácil.
fuente
La siguiente solución funcionó para mí, acaba de agregar
(representando la cadena como unicode) antes de mi cadena.
fuente
Por desgracia, esto funciona en Python 3 al menos ...
Python 3
A veces, el error está en las variables de entorno y por lo tanto
donde los errores se ignoran en la codificación.
fuente
Acabo de tener este problema y Google me llevó aquí, así que para agregar a las soluciones generales aquí, esto es lo que funcionó para mí:
Tuve esta idea después de leer la presentación de Ned .
Sin embargo, no pretendo entender completamente por qué esto funciona. Entonces, si alguien puede editar esta respuesta o poner un comentario para explicar, lo agradeceré.
fuente
type
valor? antes y después de esto? Creo que eso funciona porque al hacer ununic += value
que es lo mismounic = unic + value
que agregar una cadena y unicode, donde python asume unicode para el resultante,unic
es decir, el tipo más preciso (piense cuando hace estoa = float(1) + int(1)
, sea
convierte en un flotador) y luegovalue = unic
señalavalue
el nuevounic
objeto que resulta ser unicode.Detectamos este error cuando ejecutamos
manage.py migrate
en Django con accesorios localizados.Nuestra fuente contenía la
# -*- coding: utf-8 -*-
declaración, MySQL estaba configurado correctamente para utf8 y Ubuntu tenía el paquete de idioma y los valores apropiados/etc/default/locale
.El problema era simplemente que al contenedor Django (usamos docker) le faltaba el
LANG
var.Configuración
LANG
deen_US.UTF-8
arranque y reinicio del envase antes de volver a ejecutar las migraciones arreglaron el problema.fuente
Muchas respuestas aquí (@agf y @Andbdrew, por ejemplo) ya han abordado los aspectos más inmediatos de la pregunta OP.
Sin embargo, creo que hay un aspecto sutil pero importante que se ha ignorado en gran medida y que es muy importante para todos los que como yo terminamos aquí mientras intentamos dar sentido a las codificaciones en Python: la gestión de la representación de personajes en Python 2 vs Python 3 es muy diferente . Siento que una gran parte de la confusión tiene que ver con personas que leen sobre codificaciones en Python sin ser conscientes de la versión.
Sugiero que cualquier persona interesada en comprender la causa raíz del problema de OP comience leyendo la introducción de Spolsky a las representaciones de personajes y Unicode y luego pase a Batchelder en Unicode en Python 2 y Python 3.
fuente
Intente evitar la conversión de variable a str (variable). A veces, puede causar el problema.
Consejo simple para evitar:
El ejemplo anterior también resolverá el error de codificación.
fuente
Si tiene algo como
packet_data = "This is data"
esto, haga esto en la siguiente línea, justo después de inicializarpacket_data
:fuente
Actualización para python 3.0 y posterior. Pruebe lo siguiente en el editor de Python:
Esto establece la codificación regional predeterminada del sistema al formato UTF-8.
Puede leer más aquí en PEP 538: coaccionar la configuración regional C heredada a una configuración regional basada en UTF-8 .
fuente
Tuve este problema al intentar generar caracteres Unicode
stdout
, pero consys.stdout.write
, en lugar de imprimir (para poder admitir la salida a un archivo diferente también).De la documentación de BeautifulSoup , resolví esto con la biblioteca de códecs:
fuente
Este problema a menudo ocurre cuando un proyecto django se implementa usando Apache. Porque Apache establece la variable de entorno LANG = C en / etc / sysconfig / httpd. Simplemente abra el archivo y comente (o cambie su flavour) esta configuración. O utilice la opción lang del comando WSGIDaemonProcess, en este caso podrá establecer diferentes variables de entorno LANG en diferentes hosts virtuales.
fuente
La solución recomendada no funcionó para mí y podría vivir eliminando todos los caracteres no ascii, así que
lo que me dejó con algo despojado que no arroja errores.
fuente
Esto funcionará:
Salida:
fuente
En el caso general de escribir esta cadena de codificación no compatible (digamos ) en algún archivo (por ejemplo ), esto funciona
data_that_causes_this_error
results.txt
fuente