Кодировка дает "ascii" кодек не может кодировать символ... порядковый не в диапазоне (128) "
Я работаю над проектом Django RSS reader здесь.
RSS-канал будет читать что-то вроде "OKLAHOMA CITY (AP) - James Harden let". Кодировка RSS-канала считывает кодировку = "UTF-8", поэтому я считаю, что передаю utf-8 для уценки в фрагменте кода ниже. Em dash - это место, где он задыхается.
Я получаю ошибку Django кодека '' ascii '' не может кодировать символ u '\ u2014' в позиции 109: порядковый номер не в диапазоне (128) ", который является UnicodeEncodeError. В передаваемых переменных я вижу" OKLAHOMA CITY (AP)\u2014 Джеймс Харден". Строка кода, которая не работает:
content = content.encode(parsed_feed.encoding, "xmlcharrefreplace")
Я использую markdown 2.0, django 1.1 и python 2.4.
Какова магическая последовательность кодирования и декодирования, которую мне нужно сделать, чтобы сделать эту работу?
(В ответ на запрос Прометея. Я согласен, что форматирование помогает)
Итак, в представлениях я добавляю строку smart_unicode над строкой кодирования parsed_feed...
content = smart_unicode(content, encoding='utf-8', strings_only=False, errors='strict')
content = content = content.encode(parsed_feed.encoding, "xmlcharrefreplace")
Это подталкивает проблему к моим models.py для меня, где у меня
def save(self, force_insert=False, force_update=False):
if self.excerpt:
self.excerpt_html = markdown(self.excerpt)
# super save after this
Если я изменил метод сохранения, чтобы...
def save(self, force_insert=False, force_update=False):
if self.excerpt:
encoded_excerpt_html = (self.excerpt).encode('utf-8')
self.excerpt_html = markdown(encoded_excerpt_html)
Я получаю код ошибки "'ascii не может декодировать байт 0xe2 в позиции 141: порядковый номер не в диапазоне (128)" , потому что теперь он читает "\ xe2\x80\x94", где em emash был
Ответы
Ответ 1
Если данные, которые вы получаете, на самом деле закодированы в UTF-8, тогда это должна быть последовательность байтов - объект Python 'str' в Python 2.X
Вы можете проверить это с помощью утверждения:
assert isinstance(content, str)
Как только вы знаете, что это правда, вы можете перейти к фактической кодировке. Python не выполняет транскодирование - например, от UTF-8 до ASCII. Вы должны сначала преобразовать свою последовательность байтов в строку Unicode, расшифровав ее:
unicode_content = content.decode('utf-8')
(Если вы можете доверять parsed_feed.encoding, тогда используйте это вместо литерального "utf-8". В любом случае будьте готовы к ошибкам.)
Затем вы можете взять эту строку и закодировать ее в ASCII, заменив высокие символы на эквиваленты сущностей XML:
xml_content = unicode_content.encode('ascii', 'xmlcharrefreplace')
Таким образом, полный метод будет выглядеть примерно так:
try:
content = content.decode(parsed_feed.encoding).encode('ascii', 'xmlcharrefreplace')
except UnicodeDecodeError:
# Couldn't decode the incoming string -- possibly not encoded in utf-8
# Do something here to report the error
Ответ 2
Django предоставляет несколько полезных функций для преобразования между Unicode и bytestrings:
из django.utils.encoding import smart_unicode, smart_str
Ответ 3
Я столкнулся с этой ошибкой во время записи имени файла с zip файлом. Не удалось выполнить
ZipFile.write(root+'/%s'%file, newRoot + '/%s'%file)
и работающие
ZipFile.write(str(root+'/%s'%file), str(newRoot + '/%s'%file))