«UnicodeEncodeError: кодек« ascii »не может закодировать символ» - PullRequest
27 голосов
/ 31 октября 2009

Я пытаюсь передать большие строки случайного HTML через регулярные выражения, и мой скрипт на Python 2.6 задыхается от этого:

UnicodeEncodeError: кодек «ascii» не может кодировать символ

Я проследил его до верхнего индекса торговой марки в конце этого слова: Protection ™ - и я ожидаю встретить других подобных в будущем.

Есть ли модуль для обработки символов, отличных от ascii? или, каков наилучший способ обработать / избежать не-ascii вещей в python?

Спасибо! Полная ошибка:

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)

Полный сценарий:

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

Ответы [ 4 ]

32 голосов
/ 31 октября 2009

Вы пытаетесь конвертировать юникод в ascii в "строгом" режиме:

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

Вы, вероятно, хотите что-то вроде одного из следующих:

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
21 голосов
/ 31 октября 2009

Вы пытаетесь передать байтовую строку чему-то, но невозможно (из-за недостатка информации, которую вы предоставляете) сказать , что вы пытаетесь передать. Вы начинаете со строки Unicode, которая не может быть закодирована как ASCII (кодек по умолчанию), поэтому вам придется кодировать с помощью другого кодека (или транслитерировать его, как предлагает @ R.Pate) - но это невозможно использовать для скажем какой кодек вы должны использовать, потому что мы не знаем, что вы передаете, и поэтому не знаете, что эта неизвестная подсистема сможет принимать и обрабатывать правильно с точки зрения кодеков .

В такой полной темноте, которую вы оставляете нам, utf-8 - разумное слепое предположение (так как это кодек, который может представлять любую строку Unicode точно в виде строки байтов, и это стандартный кодек для многих целей, таких как XML) - но это не может быть чем-то большим, чем слепое предположение, до тех пор, пока вы не расскажете нам больше о , что вы пытаетесь передать этому байтуру и для каких целей.

Передача thestring.encode('utf-8') вместо голого thestring определенно позволит избежать конкретной ошибки, которую вы видите сейчас, но это может привести к особым дисплеям (или что бы вы ни пытались сделать ) с помощью этой строки!) если получатель не готов, не желает и не может принять кодировку utf-8 (и как мы можем знать, абсолютно не имея представления о том, каким может быть получатель?! -)

1 голос
/ 31 октября 2009

«Лучший» способ всегда зависит от ваших требований; итак, какие у тебя? Уместно ли игнорировать не-ASCII? Следует ли заменить ™ на «(тм)»? (Это выглядит необычно для этого примера, но быстро ломается для других кодовых точек & mdash; но это может быть именно то, что вы хотите.) Может ли исключение быть именно тем, что вам нужно; теперь вам просто нужно как-то с этим справиться?

Только вы действительно можете ответить на этот вопрос.

0 голосов
/ 13 августа 2015

Прежде всего, попробуйте установить переводы на английский язык (или любой другой, если необходимо):

sudo apt-get install language-pack-en

, который предоставляет обновления данных перевода для всех поддерживаемых пакетов (включая Python).

И убедитесь, что вы используете правильную кодировку в вашем коде.

Например:

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

Затем дважды проверьте конфигурацию вашей системы, например значение LANG или настройку локали (/etc/default/locale), и не забудьте повторно войти в сеанс.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...