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)

1396

Tengo problemas al 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 al lanzar un UnicodeEncodeError. He intentado casi todo lo que se me ocurre y, sin embargo, no he encontrado nada que funcione de forma coherente sin arrojar algún tipo de error relacionado con Unicode.

A continuación se muestra una de las secciones del 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 no estar codificadas. 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 manejo del 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 CONSISTENTEMENTE?

6
  • 1
    Si recibe estos errores como usuario en lugar de como desarrollador, consulte serverfault.com/questions/54591/… y askubuntu.com/questions/599808/…That Brazilian Guy 11/06/18 a las 0:52
  • Agregaré este punto: no use onlinegdb.com/online_python_interpreter para estas cosas. ¡Estaba usando ese intérprete para probar cosas y no está configurado correctamente para Unicode! Siempre estaba imprimiendo en formato 'B' \ nnn '' ... ¡cuando todo lo que quería era un guillemet! Probé en una máquina virtual y funcionó inmediatamente como se esperaba usando chr ()JGFMK 7 de agosto de 2018 a las 22:06
  • 4
    Prueba esto 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')). hhh 15/04/19 a las 21:48
  • @hhh Ejecuté su fragmento NameError: el nombre 'myText' no está definidoKHAN irfan 20/04/19 a las 10:31
  • 19
    Intente configurar PYTHONIOENCODING en el shell, antes de ejecutar su script:$ export PYTHONIOENCODING=utf8Noam Manos 11/08/19 a las 8:50
1455

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

Básicamente, deje de usar strpara convertir de Unicode a texto / bytes codificados.

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

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

o trabajar completamente en Unicode.

19
  • 30
    ¡acordado! una buena regla general que me enseñaron es usar la idea del "sándwich unicode". Su secuencia de comandos acepta bytes del mundo exterior, pero todo el procesamiento debe realizarse en Unicode. ¡Solo cuando esté listo para generar sus datos, debe convertirlos en bytes! Andbdrew 30/03/12 a las 12:29
  • 266
    En caso de que alguien más se confunda con esto, encontré algo extraño: mi terminal usa utf-8, y cuando printutilizo mis cadenas utf-8, funciona bien. Sin embargo, cuando canalizo la salida de mis programas a un archivo, arroja un archivo UnicodeEncodeError. De hecho, cuando se redirige la salida (en un archivo o una tubería), me parece que sys.stdout.encodinges None! Dar vueltas .encode('utf-8')resuelve el problema. drevicko 18/12/12 a las 8:15
  • 99
    @drevicko: use PYTHONIOENCODING=utf-8en su lugar, es decir, imprima cadenas Unicode y deje que el entorno establezca la codificación esperada. jfs 21 de diciembre de 2013 a las 3:51
  • 2
    @steinar: nada es válido en todos los casos. En general, a un usuario no debería importarle que utilice Python para implementar su utilidad (la interfaz no debería cambiar si decide volver a implementarla en otro idioma por cualquier motivo) y, por lo tanto, no debería esperar que el usuario esté al tanto de Python. envvars específicos. Es una mala interfaz de usuario obligar al usuario a especificar la codificación de caracteres; incruste la codificación de caracteres en el formato del informe si es necesario. Nota: ninguna codificación codificada puede ser "predeterminada sensible" en el caso general. jfs 25/11/15 a las 10:24
  • 18
    Este es un consejo malo y confuso. La razón por la que la gente usa str es porque el objeto NO ES ya una cadena, por lo que no hay un .encode()método para llamar. Cerin 5/10/2016 a las 17:59
461

¡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 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, dip, 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à

¡Ahí tienes!

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 ('cualquier_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

4
  • 93
    Nota personal: cuando intente escribir ".encode", no escriba accidentalmente ".unicode" y luego se pregunte por qué no funciona nada. Skip Huffman 24/12/12 a las 14:38
  • 11
    Buen consejo. Pero, ¿qué hace en su lugar cuando usa str (x) para imprimir objetos que pueden ser cadenas o no? str (x) funciona si x es un número, fecha y hora, booleano o cadena normal. De repente, si es un Unicode, deja de funcionar. ¿Hay alguna forma de obtener el mismo comportamiento o ahora necesitamos agregar una verificación IF para probar si el objeto es una cadena para usar .encode, y str () de lo contrario? Dirk R 25 de enero de 2018 a las 16:50
  • La misma pregunta podría hacerse con Nonevalor. Vadorequest 19/11/18 a las 13:54
  • obtuviste mi voto solo por usar "Voil \ u00E0!" ¡Brillante! Clint Eastwood 11 de agosto a las 19:58
232

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 notar que usar la opción de ignorar es peligroso porque silenciosamente elimina cualquier soporte de Unicode (e internacionalización) del código que lo usa, como se ve aquí (convertir unicode):

>>> u'City: Malmö'.encode('ascii', 'ignore').decode('ascii')
'City: Malm'
3
  • 18
    ¡Me has alegrado el día! Para utf-8, es suficiente hacer:yourstring = yourstring.encode('utf-8', 'ignore').decode('utf-8')luca76 14 de febrero de 2017 a las 15:38
  • para mí, esto funcionó, pero mi caso era diferente, estaba guardando nombres de archivos y tenía "/" en el nombre y la ruta no existía, así que tuve que usar .replace ("/", "") y así lo guardé mio guion. mientras que ignorar el ascii también funciona para el caso 'utf-8'. Akash Kandpal 5 de julio de 2018 a las 8:38
  • 1
    @ harrypotter0 para concatenar rutas de archivos correctamente os.path.join(), es un muy buen hábito cuando comienzas a hacer programación multiplataforma. :)login_not_failed 22/08/18 a las 7:36
176

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

# encoding=utf8
import sys
reload(sys)
sys.setdefaultencoding('utf8')
11
  • 7
    No hagas esto. stackoverflow.com/questions/3828723/… , aunque cuando tiene respuestas como esta stackoverflow.com/a/31137935/2141635 cerca de la parte superior de los resultados cuando busca el error, puedo ver por qué puede parecer una buena idea. Padraic Cunningham 8 de septiembre de 2016 a las 11:50
  • 26
    Probé casi todas las sugerencias en este tema y realmente ninguna funcionó para mí. Finalmente probé este. Y es realmente EL ÚNICO que funcionó simple y bien. Si alguien dice "No hagas esto, entonces ven con una solución simple. De lo contrario, usa esta. Porque es una buena copia de trabajo y una solución anterior.Richard de Ree 24 de agosto de 2017 a las 11:48
  • 4
    ¿Cómo se podría hacer esto en python3? Estaría feliz de saberlo. Kanerva Peter 7 de marzo de 2018 a las 12:24
  • 4
    Después de tanta frustración, este funcionó. Gracias un montón. Avraham Zhurba 17/06/18 a las 21:47
  • 6
    Solo agregaría unif sys.version_info.major < 3:Prof. Falken 15/07/18 a las 13:52
98

Un problema sutil que hace que incluso la impresión falle es tener las variables de entorno configuradas incorrectamente, por ejemplo. aquí LC_ALL ajustado a "C". En Debian desaconsejan configurarlo: Debian wiki en la configuración regional

$ 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à
3
  • Tengo exactamente el mismo problema, tan mal que no lo verifiqué antes de informar . Muchas gracias. Por cierto, puede reemplazar los dos primeros comandos con env|grep -E '(LC|LANG)'. Dmitry Verhoturov 8 de agosto de 2015 a las 7:28
  • Solo mis dos centavos en el problema de codificación incorrecta. Frecuentemente utilizo mcen "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 dependen ru_RU.UTF-8internamente, simplemente mueren. Probé muchas cosas de este hilo antes de descubrir el problema real. :)login_not_failed 22/08/18 a las 7:52
  • USTED ES MARAVILLOSO. En GSUTIL, mi rsync estaba fallando debido exactamente a este problema. Se corrigió el LC_ALL y todo funciona bien como vino. <3 GRACIAS <3dsignr 23 dic 2019 a las 5:24
31

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

Puede intentar instalar el language-pack-enpaquete 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 (dependiendo de los caracteres que esté intentando 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 utilizar 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 por ejemplo:

  • 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_CTYPEen cáscara.

  • Compruebe qué configuración regional admite su shell mediante:

    locale -a | grep "UTF-8"
    

Demostrando el problema y la solución en una nueva máquina virtual.

  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 un signo de marca comercial ):

    $ 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 debería resolverse:

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

    $ LC_ALL=C.UTF-8 python -c 'print(u"\u2122");'
    ™
    
7
  • 1
    ¿Qué tiene language-pack-enque ver con Python o esta pregunta? AFAIK, puede proporcionar traducciones de idiomas a los mensajes, pero no tiene nada que ver con la codificaciónAlastair McCormack 26/12/15 a las 10:47
  • 3
    En algunas distribuciones de Linux, es necesario para asegurarse de que las configuraciones regionales en inglés predeterminadas estén configuradas correctamente, especialmente cuando se ejecuta el script Python en la Terminal. Me funcionó en un momento. Ver: codificación de caractereskenorb 26 dic 2015 a las 11:00
  • Ah, vale. ¿Quiere decir si desea utilizar una configuración regional que no sea en inglés? Supongo que el usuario también tendrá que editar /etc/locale.genpara asegurarse de que su configuración regional esté construida antes de usarla. Alastair McCormack 26 dic 2015 a las 11:04
  • 1
    @AlastairMcCormack Comentó LANGdesde /etc/default/locale(como no /etc/locale.genexiste) y se ejecutó locale-gen, pero no ayudó. No estoy seguro de qué es language-pack-enexactamente lo que hace, ya que no encontré mucha documentación y enumerar su contenido no ayuda mucho. kenorb 27/12/15 a las 13:07
  • 1
    es poco probable que ya no existan locales utf-8 en un sistema de escritorio, es decir, es probable que no necesite instalar nada, solo configure LANG/ LC_CTYPE/ en su LC_ALLlugar (por ejemplo, LANG=C.UTF-8). jfs 1 de enero de 2016 a las 3:10
27

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')
7
  • 27
    "Perfectamente" no suele ser lo que realiza. Tira cosas con las que deberías averiguar cómo lidiar correctamente. tripleee 13/12/14 a las 16:53
  • 8
    simplemente eliminar "esos" caracteres (que no están en inglés) no es la solución, ya que Python debe admitir todos los idiomas, ¿no crees? alemol 9/01/15 a las 19:47
  • 8
    Voto en contra. Ésta no es la solución correcta en absoluto. Aprenda a trabajar con Unicode: joelonsoftware.com/articles/Unicode.htmlAndrew Ferrier 13/01/15 a las 13:04
  • 4
    Mire, la forma más juiciosa de presentar esta respuesta en particular es de esta manera: reconociendo que ascii confiere un cierto privilegio a ciertos idiomas y usuarios: esta es la vía de escape que puede ser explotada para aquellos usuarios que pueden estar pirateando un primer paso superficial. , el script juntos potencialmente para un trabajo preliminar antes de que se implemente el soporte completo de Unicode. lol 19/06/2016 a las 14:07
  • 6
    Si estoy escribiendo un script que solo necesita imprimir texto en inglés en stdout en una aplicación interna de la empresa, solo quiero que el problema desaparezca. Lo que sea que funcione. kagronick 11 de mayo de 2017 a las 14:11
27

Para mí, lo que funcionó fue:

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

Espero que esto ayude a alguien.

27

Con cáscara:

  1. Busque la configuración regional UTF-8 compatible con 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");'
    

Probado anteriormente en Ubuntu.

3
  • Sí, esta es la mejor respuesta corta, no podemos modificar el código fuente para usar .encodeNeo.Mxn0 19/01/20 a las 18:17
  • Lo usé en python3 y ahora funciona bien después de configurar LC_ALL. graciasAjay 18 jul.20 a las 14:03
  • gracias, de todas las respuestas, esto funcionó perfectamente para mí. lww 5 de junio a las 13:47
18

Aquí hay una repetición de algunas otras respuestas de las llamadas "evasión". 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 en replacelugar de ignoreen la llamada a codificar para el controlador de errores.

Sugerencia: ¿es posible que desee nombrar esta función en su toAsciilugar? Eso es cuestión de preferencia ...

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

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

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 información en PEP 263 .

1
  • 2
    Esto no resuelve el problema cuando el texto procesado cargado desde un archivo externo contiene codificaciones utf-8. Esto ayuda solo para los literales escritos en el script de Python dado y es solo una pista para el intérprete de Python, pero no tiene ningún impacto en el procesamiento de texto. Mikaelblomkvistsson 8 de ene. De 2019 a las 14:43
9

Siempre pongo el código a continuación en las dos primeras líneas de los archivos de Python:

# -*- coding: utf-8 -*-
from __future__ import unicode_literals
1
  • 1
    ¡Muchas gracias! No entendía por qué funcionaba en otros guiones y no en este. La respuesta es la falta del futuro ;)HamzDiou 23 jul a las 10:00
7

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

Python 3

A veces, el error está en las variables del entorno y, por lo tanto,

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.

6

Funciones de ayuda 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')
2
  • Para obtener el escaparon cadena de bytes (para convertir cadena Unicode arbitraria de bytes utilizando la codificación ASCII), se puede usar backslashreplacegestor de errores: u'\xa0'.encode('ascii', 'backslashreplace'). Aunque debe evitar dicha representación y configurar su entorno para que acepte caracteres no ascii en su lugar, ¡estamos en 2016! jfs 1 de enero de 2016 a las 3:05
  • Feliz año nuevo @JFSebastian. Me frustré con el problema de Python-Unicode y finalmente obtuve esta solución que estaba funcionando. No sabía nada de esto. De todos modos, gracias por la sugerencia. Parag Tyagi 1 de enero de 2016 a las 6:53
6

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

agent_contact.encode('utf-8')
0
4

Solo usé lo siguiente:

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

Compruebe lo que dice la documentación al respecto:

unicodedata.normalize(form, unistr) Return the normal form form for the Unicode string unistr. Valid values for form are ‘NFC’, ‘NFKC’, ‘NFD’, and ‘NFKD’.

The Unicode standard defines various normalization forms of a Unicode string, based on the definition of canonical equivalence and compatibility equivalence. In Unicode, several characters can be expressed in various way. For example, the character U+00C7 (LATIN CAPITAL LETTER C WITH CEDILLA) can also be expressed as the sequence U+0043 (LATIN CAPITAL LETTER C) U+0327 (COMBINING CEDILLA).

For each character, there are two normal forms: normal form C and normal form D. Normal form D (NFD) is also known as canonical decomposition, and translates each character into its decomposed form. Normal form C (NFC) first applies a canonical decomposition, then composes pre-combined characters again.

In addition to these two forms, there are two additional normal forms based on compatibility equivalence. In Unicode, certain characters are supported which normally would be unified with other characters. For example, U+2160 (ROMAN NUMERAL ONE) is really the same thing as U+0049 (LATIN CAPITAL LETTER I). However, it is supported in Unicode for compatibility with existing character sets (e.g. gb2312).

The normal form KD (NFKD) will apply the compatibility decomposition, i.e. replace all compatibility characters with their equivalents. The normal form KC (NFKC) first applies the compatibility decomposition, followed by the canonical composition.

Even if two unicode strings are normalized and look the same to a human reader, if one has combining characters and the other doesn’t, they may not compare equal.

Me lo resuelve. Simple y fácil.

4

Abra la terminal y dispare el siguiente comando:

export LC_ALL="en_US.UTF-8"
3

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

u "String"

(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)
2

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, lo agradeceré.

1
  • 3
    ¿Cuál es el typevalor? antes y despues de esto? Creo que la razón por la que funciona es que al hacer lo unic += valueque es lo mismo unic = unic + valueque está agregando una cadena y un unicode, donde python luego asume unicode para el resultado, unices decir, el tipo más preciso (piense en cuando hace esto a = float(1) + int(1), se aconvierte en un flotador) y luego value = unicapunta valueal nuevo unicobjeto que resulta ser Unicode. Tom Myddeltyn 24 de mayo de 2016 a las 21:16
2

Detectamos este error al ejecutar manage.py migrateDjango con dispositivos localizados.

Nuestra fuente contenía la # -*- coding: utf-8 -*-declaración, 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 Docker) le faltaba la LANGvar env.

Configuración LANGde en_US.UTF-8arranque y reinicio del envase antes de volver a ejecutar las migraciones arreglaron el problema.

2

La solución recomendada no funcionó para mí, y podría vivir con la eliminación de todos los caracteres no ascii, por lo que

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

lo que me dejó con algo despojado que no arroja errores.

1

Muchas respuestas aquí (@agf y @Andbdrew, por ejemplo) ya han abordado los aspectos más inmediatos de la pregunta del 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: Python 2 vs Python 3, la gestión de la representación de personajes es tremendamente diferente. . Siento que una gran parte de la confusión tiene que ver con la gente que lee sobre codificaciones en Python sin ser consciente de la versión.

Sugiero a cualquier persona interesada en comprender la causa raíz del problema de OP que comience por leer 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.

1
  • sí, mi error fue en python 2.7, 'a'.format (u'ñ'), y la solución correcta es no usar .encode ('utf-8') sino usar siempre cadenas Unicode, (el valor predeterminado en Python 3 ): u'a'.format (u'ñ '),Rogelio Triviño 19/11/19 a las 13:16
1

Intente 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.

1
  • esto no funciona ya que se encontrará con el error en el exceptoAurele Collinet 8/10/19 a las 10:04
1

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

f = open("results.txt", "w")
  f.write(data_that_causes_this_error.encode('utf-8'))
  f.close()
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
0

Actualización para python 3.0 y posterior. 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 regional predeterminada del sistema en el formato UTF-8.

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

0

Tuve este problema al intentar generar caracteres Unicode stdout, pero con sys.stdout.write, en lugar de imprimir (para que también pudiera admitir la salida en 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)
0

Este problema ocurre a menudo cuando un proyecto de django se despliega usando Apache. Porque 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á establecer diferentes variables de entorno LANG para diferentes hosts virtuales.

0

Esto funcionará:

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

Producción:

>>>bats
0

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

import sys
import io

sys.stdout = io.open(sys.stdout.fileno(), 'w', encoding='utf8')
print("é, à, ...")