“Ошибка UnicodeEncodeError:кодек 'ascii' не может кодировать символ”

StackOverflow https://stackoverflow.com/questions/1652904

Вопрос

Я пытаюсь передать большие строки случайного 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()
Это было полезно?

Решение

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

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

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

Другие советы

Вы пытаетесь преобразовать unicode в 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

"Наилучший" способ всегда зависит от ваших требований;итак, каковы ваши интересы?Уместно ли игнорировать не-ASCII?Следует ли вам заменить ™ на "(tm)"?(Что выглядит необычно для этого примера, но быстро ломается для других кодовых точек — но это может быть именно то, что вы хотите.) Может ли исключение быть именно тем, что вам нужно;теперь вам просто нужно каким-то образом с этим справиться?

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

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

sudo apt-get install language-pack-en

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

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

Например:

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top