Как да поправите: "UnicodeDecodeError: 'ascii' codec can't decode byte"

as3:~/ngokevin-site# nano content/blog/20140114_test-chinese.mkd
as3:~/ngokevin-site# wok
Traceback (most recent call last):
File "/usr/local/bin/wok", line 4, in
Engine()
File "/usr/local/lib/python2.7/site-packages/wok/engine.py", line 104, in init
self.load_pages()
File "/usr/local/lib/python2.7/site-packages/wok/engine.py", line 238, in load_pages
p = Page.from_file(os.path.join(root, f), self.options, self, renderer)
File "/usr/local/lib/python2.7/site-packages/wok/page.py", line 111, in from_file
page.meta['content'] = page.renderer.render(page.original)
File "/usr/local/lib/python2.7/site-packages/wok/renderers.py", line 46, in render
return markdown(plain, Markdown.plugins)
File "/usr/local/lib/python2.7/site-packages/markdown/init.py", line 419, in markdown
return md.convert(text)
File "/usr/local/lib/python2.7/site-packages/markdown/init.py", line 281, in convert
source = unicode(source)
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe8 in position 1: ordinal not in range(128). -- Note: Markdown only accepts unicode input!

Как да го поправя?

В някои други приложения за статични блогове, базирани на питон, китайският пост може да бъде публикуван успешно. Като например това приложение: http://github.com/vrypan/bucket3. В моя сайт http://bc3.brite.biz/ китайският пост може да бъде публикуван успешно.

Накрая го получих:

as3:/usr/local/lib/python2.7/site-packages# cat sitecustomize.py
# encoding=utf8  
import sys  

reload(sys)  
sys.setdefaultencoding('utf8')

Нека проверя:

as3:~/ngokevin-site# python
Python 2.7.6 (default, Dec  6 2013, 14:49:02)
[GCC 4.4.5] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> reload(sys)

>>> sys.getdefaultencoding()
'utf8'
>>>

Горното показва, че кодирането по подразбиране на Python е utf8. Тогава грешката вече не се появява.

Коментари (14)

Това е класически "проблем с Unicode". Смятам, че обяснението на този проблем е извън обхвата на отговора в StackOverflow, за да обясни напълно какво се случва.

Това е добре обяснено тук.

Накратко, предали сте нещо, което се интерпретира като низ от байтове, на нещо, което трябва да го декодира в Unicode символи, но кодекът по подразбиране (ascii) не успява.

Презентацията, към която ви насочих, съдържа съвети за избягване на това. Направете кода си "сандвич с Unicode". В Python 2 помага използването на from __future__ import unicode_literals.

Актуализация: как може да се поправи кодът:

Добре - в променливата "source" имате няколко байта. От въпроса ви не става ясно как са попаднали там - може би сте ги прочели от уеб форма? Във всеки случай те не са кодирани с ascii, но python се опитва да ги преобразува в unicode, приемайки, че са. Трябва изрично да му кажете какво е кодирането. Това означава, че трябва да знаете какво е кодирането! Това невинаги е лесно и зависи изцяло от това, откъде е дошъл този низ. Можете да експериментирате с някои често срещани кодировки - например UTF-8. Посочвате кодировката на unicode() като втори параметър:

source = unicode(source, 'utf-8')
Коментари (11)

В някои случаи, когато проверявате кодирането по подразбиране (print sys.getdefaultencoding()), се връща, че използвате ASCII. Ако промените на UTF-8, това не'работи, в зависимост от съдържанието на променливата ви. Намерих друг начин:

import sys
reload(sys)  
sys.setdefaultencoding('Cp1252')
Коментари (4)