“Ошибка UnicodeEncodeError:кодек 'ascii' не может кодировать символ”
-
22-07-2019 - |
Вопрос
Я пытаюсь передать большие строки случайного 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
) и не забудьте повторно войти в свой сеанс.