Pregunta

Estoy tratando de pasar grandes cadenas de html aleatorio a través de expresiones regulares y mi script Python 2.6 se está ahogando en esto:

UnicodeEncodeError: el códec 'ascii' no puede codificar caracteres

Lo rastreé hasta un superíndice de marca registrada al final de esta palabra: Protección & # 8482; - y espero encontrarme con otros como este en el futuro.

¿Hay un módulo para procesar caracteres no ascii? o, ¿cuál es la mejor manera de manejar / escapar cosas no ascii en python?

¡Gracias! Error completo:

E
======================================================================
ERROR: test_untitled (__main__.Untitled)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "C:\Python26\Test2.py", line 26, in test_untitled
    ofile.write(Whois + '\n')
UnicodeEncodeError: 'ascii' codec can't encode character u'\u2122' in position 1005: ordinal not in range(128)

Script completo:

from selenium import selenium
import unittest, time, re, csv, logging

class Untitled(unittest.TestCase):
    def setUp(self):
        self.verificationErrors = []
        self.selenium = selenium("localhost", 4444, "*firefox", "http://www.BaseDomain.com/")
        self.selenium.start()
        self.selenium.set_timeout("90000")

    def test_untitled(self):
        sel = self.selenium
        spamReader = csv.reader(open('SubDomainList.csv', 'rb'))
        for row in spamReader:
            sel.open(row[0])
            time.sleep(10)
            Test = sel.get_text("//html/body/div/table/tbody/tr/td/form/div/table/tbody/tr[7]/td")
            Test = Test.replace(",","")
            Test = Test.replace("\n", "")
            ofile = open('TestOut.csv', 'ab')
            ofile.write(Test + '\n')
            ofile.close()

    def tearDown(self):
        self.selenium.stop()
        self.assertEqual([], self.verificationErrors)

if __name__ == "__main__":
    unittest.main()
¿Fue útil?

Solución

Está intentando pasar una cadena de bytes a algo, pero es imposible (por la escasez de información que proporciona) decirle a a qué está tratando de pasarla. Comienza con una cadena Unicode que no puede codificarse como ASCII (el códec predeterminado), por lo tanto, tendrá que codificar mediante un códec diferente (o transliterarlo, como sugiere @ R.Pate), pero es imposible de usar para diga el códec what que debe usar, porque no sabemos qué está pasando la cadena de bytes y, por lo tanto, no sabemos qué será capaz de aceptar y procesar correctamente ese subsistema desconocido en términos de códecs.

En la oscuridad total que nos deja, utf-8 es una suposición ciega razonable (ya que es un códec que puede representar cualquier cadena Unicode exactamente como una cadena de bytes, y es el códec estándar para muchos propósitos, como XML), pero no puede ser más que una suposición ciega, hasta y a menos que nos diga más sobre qué está tratando de pasar esa cadena de bytes y para qué fines.

Pasar thestring.encode ('utf-8') en lugar de thestring desnudo definitivamente evitará el error particular que está viendo en este momento, pero puede resultar en pantallas peculiares (¡o lo que sea que intente hacer con esa cadena de bytes!) a menos que el destinatario esté listo, dispuesto y capaz de aceptar la codificación utf-8 (y cómo podríamos saberlo, tener absolutamente cero idea sobre lo que podría ser el destinatario?! -)

Otros consejos

Estás intentando convertir unicode a ascii en " estricto " modo:

>>> help(str.encode)
Help on method_descriptor:

encode(...)
    S.encode([encoding[,errors]]) -> object

    Encodes S using the codec registered for encoding. encoding defaults
    to the default encoding. errors may be given to set a different error
    handling scheme. Default is 'strict' meaning that encoding errors raise
    a UnicodeEncodeError. Other possible values are 'ignore', 'replace' and
    'xmlcharrefreplace' as well as any other name registered with
    codecs.register_error that is able to handle UnicodeEncodeErrors.

Probablemente desee algo como uno de los siguientes:

s = u'Protection™'

print s.encode('ascii', 'ignore')    # removes the ™
print s.encode('ascii', 'replace')   # replaces with ?
print s.encode('ascii','xmlcharrefreplace') # turn into xml entities
print s.encode('ascii', 'strict')    # throw UnicodeEncodeErrors

El " mejor " siempre depende de sus requisitos; Entonces, ¿cuáles son los tuyos? ¿Es apropiado ignorar no ASCII? ¿Debería reemplazar ™ con " (tm) " ;? (Lo que parece elegante para este ejemplo, pero se descompone rápidamente para otros puntos de código, pero puede ser justo lo que desea). ¿Podría la excepción ser exactamente lo que necesita? ahora solo necesitas manejarlo de alguna manera?

Solo usted realmente puede responder esta pregunta.

En primer lugar, intente instalar traducciones para el idioma inglés (o cualquier otro si es necesario):

sudo apt-get install language-pack-en

que proporciona actualizaciones de datos de traducción para todos los paquetes compatibles (incluido Python).

Y asegúrese de usar la codificación correcta en su código.

Por ejemplo:

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

Luego verifique la configuración de su sistema como el valor de LANG o la configuración de locale ( / etc / default / locale ) y no olvide volver a iniciar sesión en su sesión .

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top