“UnicodeEncodeError: il codec ‘ascii’ non può codificare il carattere”

Sto cercando di passare grandi stringhe di html casuale attraverso le espressioni regolari e il mio script Python 2.6 sta soffocando su questo:

UnicodeEncodeError: il codec ‘ascii’ non può codificare il carattere

Ho risalito a un apice del marchio alla fine di questa parola: Protection ™ – e mi aspetto di incontrare altri simili in futuro.

Esiste un modulo per elaborare caratteri non ASCII? o, qual è il modo migliore per gestire / sfuggire a cose non ascii in python?

Grazie! Errore 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() 

Stai provando a passare un test di verifica a qualcosa, ma è imansible (dalla scarsità di informazioni che fornisci) dire a cosa stai cercando di trasmetterlo. Si inizia con una stringa Unicode che non può essere codificata come ASCII (il codec predefinito), quindi sarà necessario codificare con un codec diverso (o traslitterarlo, come suggerisce @ R.Pate) – ma è imansible utilizzarlo per di ‘codec che dovresti usare, perché non sappiamo cosa stai passando il bytestring e quindi non sappiamo cosa quel sottosistema sconosciuto sarà in grado di accettare ed elaborare correttamente in termini di codec.

In un’oscurità così totale come ci lasci dentro, utf-8 è una ragionevole ipotesi cieca (dal momento che è un codec che può rappresentare qualsiasi stringa Unicode esattamente come un bytestring, ed è il codec standard per molti scopi, come XML) – ma non può essere più di un’ipotesi cieca, fino a quando e a meno che tu non voglia dirci di più su ciò che stai cercando di trasmettere a quello, e per quali scopi.

Passare thestring.encode('utf-8') piuttosto che il thestring nudo thestring sicuramente l’errore particolare che stai vedendo in questo momento, ma potrebbe causare visualizzazioni particolari (o qualsiasi altra cosa tu stia cercando di fare con questo test! ) a meno che il destinatario non sia pronto, disposto e in grado di accettare la codifica utf-8 (e come potremmo NOI, non avendo assolutamente idea di cosa potrebbe essere il destinatario?!)

Stai cercando di convertire unicode in ascii in modalità “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. 

Probabilmente vuoi qualcosa come uno dei seguenti:

 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 

Il modo “migliore” dipende sempre dalle tue esigenze; quindi, quali sono i tuoi? Ignorare non ASCII è appropriato? Dovresti sostituire ™ con “(tm)”? (Che sembra carino per questo esempio, ma si scompone rapidamente per altri codepoint, ma potrebbe essere proprio quello che vuoi.) L’eccezione potrebbe essere esattamente ciò di cui hai bisogno; ora hai solo bisogno di gestirlo in qualche modo?

Solo tu puoi davvero rispondere a questa domanda.

Prima di tutto, prova ad installare le traduzioni per la lingua inglese (o qualsiasi altra se necessario):

 sudo apt-get install language-pack-en 

che fornisce aggiornamenti dei dati di traduzione per tutti i pacchetti supportati (incluso Python).

E assicurati di utilizzare la giusta codifica nel codice.

Per esempio:

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

Quindi ricontrolla la configurazione del tuo sistema come il valore di LANG o la configurazione delle /etc/default/locale locali ( /etc/default/locale ) e non dimenticarti di accedere nuovamente alla sessione.