编码给出''ascii'编解码器不能编码字符...序数不在范围内(128)“

时间:2010-03-25 04:19:24

标签: python django unicode character-encoding

我正在研究Django RSS阅读器项目here

RSS提要将读取类似“OKLAHOMA CITY(AP) - James Harden let”的内容。 RSS feed的编码读取encoding =“UTF-8”,所以我相信我在下面的代码片段中将utf-8传递给markdown。 em dash是它窒息的地方。

我得到Django错误“'ascii'编解码器无法编码位置109中的字符u'\ u2014':ordinal not in range(128)”这是一个UnicodeEncodeError。在传递的变量中,我看到“OKLAHOMA CITY(AP)\ u2014 James Harden”。无效的代码行是:

content = content.encode(parsed_feed.encoding, "xmlcharrefreplace")

我正在使用markdown 2.0,django 1.1和python 2.4。

我需要做的编码和解码的神奇序列是什么?


(回应普罗米修斯的要求。我同意格式化有帮助)

因此,在视图中,我在parsed_feed编码行上方添加了一条smart_unicode行...

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'编解码器无法解码位置141的字节0xe2:序号不在范围内(128)”因为现在它读取“\ xe2 \ x80 \ x94” em dash是

3 个答案:

答案 0 :(得分:12)

如果你接收的数据实际上是用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

答案 1 :(得分:4)

答案 2 :(得分:0)

在使用zip文件写入文件名时遇到此错误。以下失败

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

以及以下工作

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