Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

397
Views
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)

Tengo problemas para manejar 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 al lanzar un 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.

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 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, las 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 que pueda solucionar este problema CONSTANTEMENTE?

over 4 years ago · Santiago Trujillo
34 answers
Answer question

0

Puede usar unicodedata para evitar UnicodeEncodeError. Aquí hay un ejemplo:

 import unicodedata agent_telno = agent.find('div', 'agent_contact_number') agent_telno = unicodedata.normalize("NFKD", agent_telno) #it will remove all unwanted character like '\xa0' agent_telno = '' if agent_telno is None else agent_telno.contents[0] p.agent_info = str(agent_contact + ' ' + agent_telno).strip()
over 4 years ago · Santiago Trujillo Report

0

Puede establecer la codificación de caracteres en UTF-8 antes de ejecutar su secuencia de comandos:

 export LC_CTYPE="en_US.UTF-8"

Esto generalmente debería resolver el problema.

over 4 years ago · Santiago Trujillo Report

0

Esto funciona para mi:

 export LC_CTYPE="en_US.UTF-8"
over 4 years ago · Santiago Trujillo Report

0

En caso de que sea un problema con una declaración de impresión, muchas veces es solo un problema con la impresión del terminal. Esto me ayudó: export PYTHONIOENCODING=UTF-8

over 4 years ago · Santiago Trujillo Report

0

Respuesta tardía, pero este error está relacionado con la codificación de su terminal que no admite ciertos caracteres.
Lo arreglé en python3 usando:

 import sys import io sys.stdout = io.open(sys.stdout.fileno(), 'w', encoding='utf8') print("é, à, ...")
over 4 years ago · Santiago Trujillo Report

0

Abra la terminal y ejecute el siguiente comando:

 export LC_ALL="en_US.UTF-8"
over 4 years ago · Santiago Trujillo Report

0

Actualización para python 3.0 y posteriores. Pruebe lo siguiente en el editor de python:

 locale-gen en_US.UTF-8 export LANG=en_US.UTF-8 LANGUAGE=en_US.en LC_ALL=en_US.UTF-8

Esto establece la codificación local predeterminada del sistema en el formato UTF-8.

Se puede leer más aquí en PEP 538 -- Conversión de la configuración regional C heredada a una configuración regional basada en UTF-8 .

over 4 years ago · Santiago Trujillo Report

0

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, terminaron aquí mientras intentaban dar sentido a las codificaciones en Python: la gestión de la representación de caracteres de Python 2 y Python 3 es muy diferente. . Siento que una gran parte de la confusión tiene que ver con las personas que leen sobre codificaciones en Python sin conocer la versión.

Sugiero a cualquier persona interesada en comprender la causa raíz del problema OP que comience leyendo la introducción de Spolsky a las representaciones de caracteres y Unicode y luego pase a Batchelder en Unicode en Python 2 y Python 3.

over 4 years ago · Santiago Trujillo Report

0

Tuve este problema al tratar de enviar caracteres Unicode a stdout , pero con sys.stdout.write , en lugar de imprimir (para que también pudiera admitir la salida a un archivo diferente).

De la propia documentación de BeautifulSoup , resolví esto con la biblioteca de códecs:

 import sys import codecs def main(fIn, fOut): soup = BeautifulSoup(fIn) # Do processing, with data including non-ASCII characters fOut.write(unicode(soup)) if __name__ == '__main__': with (sys.stdin) as fIn: # Don't think we need codecs.getreader here with codecs.getwriter('utf-8')(sys.stdout) as fOut: main(fIn, fOut)
over 4 years ago · Santiago Trujillo Report

0

En cáscara:

  1. Encuentre la configuración regional compatible con UTF-8 mediante el siguiente comando:

     locale -a | grep "UTF-8"
  2. Exportarlo, antes de ejecutar el script, por ejemplo:

     export LC_ALL=$(locale -a | grep UTF-8)

    o manualmente como:

     export LC_ALL=C.UTF-8
  3. Pruébelo imprimiendo un carácter especial, por ejemplo, ™ :

     python -c 'print(u"\u2122");'

Anteriormente probado en Ubuntu.

over 4 years ago · Santiago Trujillo Report

0

Por desgracia, esto funciona en Python 3 al menos ...

Pitón 3

A veces, el error está en las variables de entorno y acaba así.

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

donde los errores se ignoran en la codificación.

over 4 years ago · Santiago Trujillo Report

0

Trate de evitar la conversión de variable a str(variable). A veces, puede causar el problema.

Consejo simple para evitar:

 try: data=str(data) except: data = data #Don't convert to String

El ejemplo anterior también resolverá el error de codificación.

over 4 years ago · Santiago Trujillo Report

0

Este problema ocurre a menudo cuando un proyecto Django se implementa usando Apache. Debido a que Apache establece la variable de entorno LANG=C en /etc/sysconfig/httpd. Simplemente abra el archivo y comente (o cambie a su estilo) esta configuración. O use la opción lang del comando WSGIDaemonProcess, en este caso podrá configurar diferentes variables de entorno LANG para diferentes hosts virtuales.

over 4 years ago · Santiago Trujillo Report

0

La solución recomendada no funcionó para mí, y podría vivir tirando todos los caracteres que no son ascii, por lo que

 s = s.encode('ascii',errors='ignore')

lo cual me dejo algo despojado que no arroja errores.

over 4 years ago · Santiago Trujillo Report

0

Esto funcionará:

 >>>print(unicodedata.normalize('NFD', re.sub("[\(\[].*?[\)\]]", "", "bats\xc3\xa0")).encode('ascii', 'ignore'))

Producción:

 >>>bats
over 4 years ago · Santiago Trujillo Report

0

En el caso general de escribir esta cadena de codificación no admitida (digamos data_that_causes_this_error ) en algún archivo (por ejemplo, results.txt ), esto funciona

 f = open("results.txt", "w") f.write(data_that_causes_this_error.encode('utf-8')) f.close()
over 4 years ago · Santiago Trujillo Report

0

Necesitas leer el Python Unicode HOWTO . Este error es el primer ejemplo .

Básicamente, deje de usar str para convertir de unicode a texto/bytes codificados.

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

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

o trabajar enteramente en Unicode.

over 4 years ago · Santiago Trujillo Report

0

¡Este es un punto de dolor 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é 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 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à

Voil\u00E0!

El problema es que cuando llama a str(), python usa la codificación de caracteres predeterminada para intentar codificar los bytes que le dio, que en su 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 usando utf-8.

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

over 4 years ago · Santiago Trujillo Report

0

De hecho, descubrí que, en la mayoría de mis casos, simplemente eliminar esos caracteres es mucho más simple:

 s = mystring.decode('ascii', 'ignore')
over 4 years ago · Santiago Trujillo Report

0

Un problema sutil que hace que incluso la impresión falle es tener las variables de entorno configuradas incorrectamente, p. aquí LC_ALL establecido en "C". En Debian desaconsejan configurarlo: Debian wiki on Locale

 $ echo $LANG en_US.utf8 $ echo $LC_ALL C $ python -c "print (u'voil\u00e0')" Traceback (most recent call last): File "<string>", line 1, in <module> UnicodeEncodeError: 'ascii' codec can't encode character u'\xe0' in position 4: ordinal not in range(128) $ export LC_ALL='en_US.utf8' $ python -c "print (u'voil\u00e0')" voilà $ unset LC_ALL $ python -c "print (u'voil\u00e0')" voilà
over 4 years ago · Santiago Trujillo Report

0

Encontré un trabajo elegante para eliminar los símbolos y continuar manteniendo la cadena como la siguiente:

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

Es importante tener en cuenta que usar la opción ignorar es peligroso porque elimina silenciosamente cualquier compatibilidad con 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'
over 4 years ago · Santiago Trujillo Report

0

Para mí, lo que funcionó fue:

 BeautifulSoup(html_text,from_encoding="utf-8")

Espero que esto ayude a alguien.

over 4 years ago · Santiago Trujillo Report

0

El problema es que está intentando imprimir un carácter Unicode, pero su terminal no lo admite.

Puede intentar instalar language-pack-en para solucionarlo:

 sudo apt-get install language-pack-en

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 (según los caracteres que intente imprimir).

En algunas distribuciones de Linux, es necesario para asegurarse de que las configuraciones regionales predeterminadas en inglés estén configuradas correctamente (para que los caracteres Unicode puedan ser manejados por shell/terminal). 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:

 open(foo, encoding='utf-8')

Si aún tiene un problema, vuelva a verificar la configuración de su sistema, como:

  • Su archivo de configuración regional ( /etc/default/locale ), que debería tener, por ejemplo,

     LANG="en_US.UTF-8" LC_ALL="en_US.UTF-8"

    o:

     LC_ALL=C.UTF-8 LANG=C.UTF-8
  • Valor de LANG / LC_CTYPE en shell.

  • Compruebe qué configuración regional admite su shell haciendo lo siguiente:

     locale -a | grep "UTF-8"

Demostración del problema y la solución en una máquina virtual nueva.

  1. Inicialice y aprovisione la VM (por ejemplo, usando vagrant ):

     vagrant init ubuntu/trusty64; vagrant up; vagrant ssh

    Ver: cajas de Ubuntu disponibles . .

  2. Impresión de caracteres Unicode (como el signo de marca comercial como ™ ):

     $ python -c 'print(u"\u2122");' Traceback (most recent call last): File "<string>", line 1, in <module> UnicodeEncodeError: 'ascii' codec can't encode character u'\u2122' in position 0: ordinal not in range(128)
  3. Ahora instalando language-pack-en :

     $ sudo apt-get -y install language-pack-en The following extra packages will be installed: language-pack-en-base Generating locales... en_GB.UTF-8... /usr/sbin/locale-gen: done Generation complete.
  4. Ahora el problema debe ser resuelto:

     $ python -c 'print(u"\u2122");' ™
  5. De lo contrario, intente con el siguiente comando:

     $ LC_ALL=C.UTF-8 python -c 'print(u"\u2122");' ™
over 4 years ago · Santiago Trujillo Report

0

Funciones auxiliares simples que se encuentran aquí .

 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')
over 4 years ago · Santiago Trujillo Report

0

Acabo de tener este problema, y Google me llevó 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 la presentación de Ned .

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

over 4 years ago · Santiago Trujillo Report

0

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

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

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

over 4 years ago · Santiago Trujillo Report

0

Acabo de usar lo siguiente:

 import unicodedata message = unicodedata.normalize("NFKD", message)

Compruebe lo que dice la documentación al respecto:

unicodedata.normalize(form, unistr) Devuelve el formulario normal para la cadena Unicode unistr. Los valores válidos para el formulario son 'NFC', 'NFKC', 'NFD' y 'NFKD'.

El estándar Unicode define varias formas de normalización de una cadena Unicode, según la definición de equivalencia canónica y equivalencia de compatibilidad. En Unicode, varios caracteres se pueden expresar de varias formas. Por ejemplo, el carácter U+00C7 (LETRA C MAYÚSCULA LATINA CON CEDILLA) también se puede expresar como la secuencia U+0043 (LETRA C MAYÚSCULA LATINA) U+0327 (CEDILLA COMBINADA).

Para cada carácter, hay dos formas normales: la forma normal C y la forma normal D. La forma normal D (NFD) también se conoce como descomposición canónica y traduce cada carácter a su forma descompuesta. La forma normal C (NFC) primero aplica una descomposición canónica, luego vuelve a componer caracteres precombinados.

Además de estas dos formas, hay dos formas normales adicionales basadas en la equivalencia de compatibilidad. En Unicode, se admiten ciertos caracteres que normalmente se unificarían con otros caracteres. Por ejemplo, U+2160 (NÚMERO ROMANO UNO) es realmente lo mismo que U+0049 (LETRA I MAYÚSCULA LATINA). Sin embargo, se admite en Unicode por compatibilidad con juegos de caracteres existentes (p. ej., gb2312).

La forma normal KD (NFKD) aplicará la descomposición de compatibilidad, es decir, reemplazará todos los caracteres de compatibilidad con sus equivalentes. La forma normal KC (NFKC) aplica primero la descomposición de compatibilidad, seguida de la composición canónica.

Incluso si dos cadenas Unicode están normalizadas y parecen iguales para un lector humano, si una tiene caracteres combinados y la otra no, es posible que no se comparen de la misma manera.

Me lo soluciona. Simple y fácil.

over 4 years ago · Santiago Trujillo Report

0

bueno, probé todo pero no sirvió de nada, después de buscar en Google me di cuenta de lo siguiente y me ayudó. Python 2.7 está en uso.

 # encoding=utf8 import sys reload(sys) sys.setdefaultencoding('utf8')
over 4 years ago · Santiago Trujillo Report

0

Aquí hay un refrito de algunas otras respuestas llamadas "descartar". Hay situaciones en las que simplemente deshacerse de los caracteres/cadenas problemáticos es una buena solución, a pesar de las protestas expresadas aquí.

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

Probándolo:

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

Resultados:

 1 test 98° 98

ACTUALIZACIÓN: Mi respuesta original fue escrita para Python 2. Para Python 3 :

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

Nota: si prefiere dejar un ? indicador donde están los caracteres Unicode "inseguros", especifique replace en lugar de ignore en la llamada para codificar para el controlador de errores.

Sugerencia: ¿es posible que desee nombrar esta función toAscii en su lugar? eso es cuestion de preferencia...

Finalmente, aquí hay una versión PY2/3 más robusta que usa six , donde opté por replace , y agregué algunos intercambios de caracteres para reemplazar las comillas y apóstrofes elegantes de Unicode que se curvan hacia la izquierda o hacia la derecha con los simples verticales que son parte del conjunto ascii . Usted mismo puede ampliar tales intercambios:

 from six import PY2, iteritems CHAR_SWAP = { u'\u201c': u'"' , u'\u201D': u'"' , u'\u2018': u"'" , u'\u2019': u"'" } def toAscii( text ) : try: for k,v in iteritems( CHAR_SWAP ): text = text.replace(k,v) except: pass try: return str( text ) if PY2 else bytes( text, 'replace' ).decode('ascii') except UnicodeEncodeError: return text.encode('ascii', 'replace').decode('ascii') except: return "" if __name__ == '__main__': print( toAscii( u'testin\u2019' ) )
over 4 years ago · Santiago Trujillo Report

0

La siguiente solución funcionó para mí, recién agregada

u "Cadena"

(que representa la cadena como Unicode) antes de mi cadena.

 result_html = result.to_html(col_space=1, index=False, justify={'right'}) text = u""" <html> <body> <p> Hello all, <br> <br> Here's weekly summary report. Let me know if you have any questions. <br> <br> Data Summary <br> <br> <br> {0} </p> <p>Thanks,</p> <p>Data Team</p> </body></html> """.format(result_html)
over 4 years ago · Santiago Trujillo Report

0

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

 agent_contact.encode('utf-8')
over 4 years ago · Santiago Trujillo Report

0

Siempre pongo el siguiente código en las dos primeras líneas de los archivos de python:

 # -*- coding: utf-8 -*- from __future__ import unicode_literals
over 4 years ago · Santiago Trujillo Report

0

Si tiene algo como packet_data = "This is data" , haga esto en la siguiente línea, justo después de inicializar packet_data :

 unic = u'' packet_data = unic
over 4 years ago · Santiago Trujillo Report

0

Encontramos este error cuando manage.py migrate en Django con accesorios 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 apropiados en /etc/default/locale .

El problema era simplemente que al contenedor de Django (nosotros usamos la ventana acoplable) le faltaba la variable de entorno LANG .

Establecer LANG en en_US.UTF-8 y reiniciar el contenedor antes de volver a ejecutar las migraciones solucionó el problema.

over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!