Como corrigir: "UnicodeDecodeError: 'ascii' codec can't decodificar 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!

Como consertá-lo?

Em alguns outros aplicativos de blogs estáticos baseados em python, o post chinês pode ser publicado com sucesso. Tal como este aplicativo: http://github.com/vrypan/bucket3. No meu site http://bc3.brite.biz/, o post chinês pode ser publicado com sucesso.

Finalmente consegui:

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

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

Deixa-me verificar:

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'
>>>

O acima mostra que a codificação padrão de píton é utf8. Então o erro não é mais.

Comentários (14)

Este é o clássico "edição unicode". Eu acredito que explicar isto está além do escopo de uma resposta StackOverflow para explicar completamente o que está acontecendo.

Está bem explicado aqui.

Em resumo muito breve, você passou algo que está sendo interpretado como uma seqüência de bytes para algo que precisa decodificá-lo em caracteres Unicode, mas o codec padrão (ascii) está falhando.

A apresentação que lhe indiquei dá conselhos para evitar isto. Faça do seu código um "unicode sanduíche". Em Python 2, o uso do `future__ import unicode_literals' ajuda.

Atualização: como o código pode ser corrigido:

OK - na sua variável "fonte" você tem alguns bytes. Não está claro na sua pergunta como eles entraram lá - talvez você os tenha lido de um formulário web? Em qualquer caso, eles não são codificados com ascii, mas python está tentando convertê-los em unicode, assumindo que são. Você precisa dizer explicitamente o que é a codificação. Isto significa que você precisa saber o que é a codificação! Isso nem sempre é fácil, e depende inteiramente de onde esta string veio. Você poderia experimentar algumas codificações comuns - por exemplo UTF-8. Você diz unicode() a codificação como um segundo parâmetro:

source = unicode(source, 'utf-8')
Comentários (11)

Em alguns casos, quando você verifica sua codificação padrão (print sys.getdefaultencoding()), ele retorna que você está utilizando ASCII. Se você mudar para UTF-8, ele não't funciona, dependendo do conteúdo da sua variável. Eu encontrei outra maneira:

import sys
reload(sys)  
sys.setdefaultencoding('Cp1252')
Comentários (4)