Ответ 1
Попробуйте его декодировать:
> print u'abcdé'.encode('utf-8')
> abcdé
> print u'abcdé'.encode('utf-8').decode('utf-8')
> abcdé
Я пытаюсь разобрать кучу xml файлов с библиотекой xml.dom.minidom, чтобы извлечь некоторые данные и поместить их в текстовый файл. Большинство XML файлов идут хорошо, но для некоторых из них я получаю следующую ошибку при вызове minidom.parsestring():
UnicodeEncodeError: кодек ascii не может кодировать символ u '\ u2019' в позиции 5189: порядковый номер не в диапазоне (128)
Это происходит и для некоторых других символов, отличных от ascii. Мой вопрос: какие у меня варианты? Должен ли я каким-то образом убрать/заменить все те неанглийские символы, прежде чем разбираться с XML файлами?
Попробуйте его декодировать:
> print u'abcdé'.encode('utf-8')
> abcdé
> print u'abcdé'.encode('utf-8').decode('utf-8')
> abcdé
Minidom напрямую не поддерживает синтаксический анализ строк Unicode; это то, что исторически имело плохую поддержку и стандартизацию. Многие инструменты XML распознают только потоки байтов, которые могут потреблять XML-парсер.
Если у вас есть простые файлы, вы должны либо прочитать их как строки байтов (не Unicode!), и передать это на parseString()
, либо просто использовать parse()
, который будет читать файл напрямую.
Если ваша строка - 'str':
xmldoc = minidom.parseString(u'{0}'.format(str).encode('utf-8'))
Это сработало для меня.
Я знаю, что O.P спрашивал о разборе строк, но у меня было такое же исключение при написании модели DOM в файл через Document.writexml(...). Если люди с этой (связанной) проблемой приземлится здесь, я предложу свое решение.
Мой код, который бросал UnicodeEncodeError, выглядел так:
with tempfile.NamedTemporaryFile(delete=False) as fh: dom.writexml(fh, encoding="utf-8")
Обратите внимание, что параметр "encoding" влияет только на заголовок XML и не влияет на обработку данных. Чтобы исправить это, я изменил его на:
with tempfile.NamedTemporaryFile(delete=False) as fh: fh = codecs.lookup("utf-8")[3](fh) dom.writexml(fh, encoding="utf-8")
Это обернет дескриптор файла экземпляром encodings.utf_8.StreamWriter, который обрабатывает данные как UTF-8, а не ASCII, и UnicodeEncodeError ушел. У меня появилась идея прочитать источник xml.dom.minidom.Node.toprettyxml(...).
Я встречаюсь с этой ошибкой несколько раз, и мой хакерский способ справиться с этим - это просто сделать это:
def getCleanString(word):
str = ""
for character in word:
try:
str_character = str(character)
str = str + str_character
except:
dummy = 1 # this happens if character is unicode
return str
Конечно, это, вероятно, глупый способ сделать это, но он выполняет работу для меня, и мне не стоит ничего в скорости.