"UnicodeEncodeError:' ascii ' codec ne peut pas encoder le caractère"

j'essaie de passer de grandes chaînes de caractères HTML aléatoires à travers des expressions régulières et mon script python 2.6 s'étouffe là-dessus:

UnicodeEncodeError:' ascii 'codec ne peut pas encoder le caractère

Je l'ai tracé jusqu'à un exposant de marque à la fin de ce mot: Protection™ -- et je m'attends à rencontrer d'autres comme ça à l'avenir.

y a-t-il un module pour traiter les caractères non ascii? ou, quelle est la meilleure façon de gérer/échapper des choses non-ascii en python?

Merci! Erreur complète:

E
======================================================================
ERROR: test_untitled (__main__.Untitled)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "C:Python26Test2.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 Complet:

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()
26
demandé sur Mat 2009-10-31 03:07:48

4 réponses

vous essayez de passer un bytestring à quelque chose, mais il est impossible (de la rareté de l'information que vous fournissez) de dire quoi vous essayez de passer à. Vous commencez avec une chaîne Unicode qui ne peut pas être encodée en ASCII( le codec par défaut), donc, vous devrez Encoder par un codec différent (ou le translitérer, comme @R. Pate le suggère) -- mais il est impossible de dire ce que codec vous devriez utiliser, parce que nous ne savons pas ce que vous êtes passer le bytestring et donc ne savent pas ce que ce sous-système inconnu va être en mesure d'accepter et de traiter correctement en termes de codecs.

dans l'obscurité totale dans laquelle vous nous laissez, utf-8 est une supposition aveugle raisonnable (puisque c'est un codec qui peut représenter n'importe quelle chaîne Unicode exactement comme un bytestring, et c'est le codec standard pour beaucoup de buts, tels que XML) -- mais cela ne peut pas être plus qu'une supposition aveugle, jusqu'à et à moins que vous allez nous en dire plus à propos de ce vous essayez de passer cette bytestring, et à quelles fins.

passer thestring.encode('utf-8') plutôt que nu thestring permettra certainement d'éviter l'erreur particulière que vous voyez en ce moment, mais il peut en résulter des affichages particuliers (ou quoi que ce soit est vous essayez de faire avec ce bytestring!) à moins que le destinataire ne soit prêt, disposé et capable d'accepter l'encodage utf-8 (et comment pourrions-nous savoir, ayant absolument zéro idée de ce que le destinataire pourrait être?!- )

21
répondu Alex Martelli 2009-10-31 01:12:21

vous essayez de convertir unicode en ascii en mode "strict":

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

vous voulez probablement quelque chose comme l'un des suivants:

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
31
répondu Seth 2009-10-31 00:58:40

La "meilleure" façon dépend toujours de vos besoins; alors, quels sont les vôtres? Est-il approprié d'ignorer les non-ASCII? Devez-vous remplacer ™ par "(tm)"? (Qui semble fantaisie pour cet exemple, mais se décompose rapidement pour d'autres codépoints-mais il peut être juste ce que vous voulez.) Pourrait l'exception être exactement ce dont vous avez besoin; maintenant, il vous suffit de le manipuler en quelque sorte?

vous seul pouvez vraiment répondre à cette question.

1
répondu 2009-10-31 00:31:55

tout d'abord, essayez d'installer des traductions pour la langue anglaise (ou toute autre si nécessaire):

sudo apt-get install language-pack-en

qui fournit des mises à jour des données de traduction pour tous les paquets pris en charge (y compris Python).

Et assurez-vous d'utiliser le bon encodage dans votre code.

par exemple:

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

puis double vérifier la configuration de votre système comme la valeur LANG ou la configuration de locale ( /etc/default/locale ) et n'oubliez pas de vous reconnecter à votre session.

0
répondu kenorb 2015-08-13 12:11:57