Кодирование дает «кодек« ascii »не может кодировать символ… порядковый номер не в диапазоне (128)» - PullRequest
14 голосов
/ 25 марта 2010

Я работаю в проекте чтения RSS Django здесь .

В ленте RSS будет что-то вроде «ОКЛАХОМА СИТИ (AP) - Джеймс Харден, пусть». Кодировка RSS-ленты выглядит следующим образом: encoding = "UTF-8", поэтому я полагаю, что передаю utf-8 для уценки в приведенном ниже фрагменте кода. Эм тире, где он задыхается.

Я получаю ошибку Django «кодека ascii» не может закодировать символ u '\ u2014' в позиции 109: порядковый номер не в диапазоне (128) », что является ошибкой UnicodeEncodeError. В передаваемых переменных я вижу «Город Оклахома (AP) - Джеймс Харден». Неработающая строка кода:

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", где их тире было

Ответы [ 3 ]

12 голосов
/ 31 декабря 2011

Если данные, которые вы получаете, на самом деле кодируются в 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
4 голосов
/ 25 марта 2010
0 голосов
/ 07 сентября 2012

Я столкнулся с этой ошибкой при записи имени файла в zip-файл.Следующее не удалось

ZipFile.write(root+'/%s'%file, newRoot + '/%s'%file)

и следующее сработало

ZipFile.write(str(root+'/%s'%file), str(newRoot + '/%s'%file))
...