Domanda

Sto cercando di passare grandi stringhe di HTML casuale attraverso espressioni regolari e il mio script Python 2.6 mi sta soffocando:

UnicodeEncodeError: il codec 'ascii' non può codificare il carattere

L'ho rintracciato in 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()
È stato utile?

Soluzione

Stai tentando di passare a una limitazione a qualcosa, ma è impossibile (dalla scarsità di informazioni fornite) dire a a cosa stai cercando di passarlo. Inizi con una stringa Unicode che non può essere codificata come ASCII (il codec predefinito), quindi dovrai codificare con un codec diverso (o traslitterlo, come suggerisce @ R.Pate) - ma è impossibile usarlo dì quale codec dovresti usare, perché non sappiamo cosa stai passando per il bytestring e quindi non sappiamo cosa quel sottosistema sconosciuto sarà in grado di accettare ed elaborare correttamente in termini di codec.

Nell'oscurità totale in cui ci lasci, utf-8 è una supposizione cieca ragionevole (poiché è 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 altro che un'ipotesi cieca, fino a quando e a meno che non ci dirai di più su cosa stai cercando di superare questo restringimento e per quali scopi.

Il passaggio di thestring.encode ('utf-8') anziché il thestring nudo eviterà sicuramente il particolare errore che stai vedendo in questo momento, ma potrebbe causare display peculiari (o qualunque cosa sia che stai cercando di fare con questo restringimento!) a meno che il destinatario non sia pronto, disposto e in grado di accettare la codifica utf-8 (e come potremmo saperlo, avendo assolutamente zero idea di cosa potrebbe essere il destinatario?! -)

Altri suggerimenti

Stai cercando di convertire unicode in ascii in " rigoroso " Modalità:

>>> 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 di simile a 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 "migliore" il modo dipende sempre dalle tue esigenze; quindi quali sono i tuoi? Ignorare non ASCII è appropriato? Se sostituisci & # 8482; con " (tm) " ;? (Il che sembra elegante per questo esempio, ma si interrompe rapidamente per altri punti di codice & # 8212; ma potrebbe essere proprio quello che vuoi.) L'eccezione potrebbe essere esattamente quello che ti serve; ora devi solo gestirlo in qualche modo?

Solo tu puoi veramente rispondere a questa domanda.

Prima di tutto, prova a installare 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 codifica corretta nel tuo codice.

Ad esempio:

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

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

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top