Python Unicode CSV 导出(使用 Django)

5 投票
3 回答
4390 浏览
提问于 2025-04-16 05:27

我正在使用一个Django应用程序将字符串导出到CSV文件。这个字符串是通过前端表单提交的消息。但是,当输入中包含unicode单引号时,我遇到了一个错误。

UnicodeEncodeError: 'ascii' codec can't encode character u'\u2019' 
  in position 200: ordinal not in range(128)

我尝试用下面的代码将unicode转换为ascii,但仍然出现类似的错误。

UnicodeEncodeError: 'ascii' codec can't encode characters in 
position 0-9: ordinal not in range(128)

我浏览了很多网站,学到了很多关于unicode的知识,但我仍然无法将这个unicode转换为ascii。我并不在乎算法是否会删除unicode字符。注释的行显示了我尝试过的一些不同选项,但错误依然存在。

import csv
import unicodedata

...

#message = unicode( unicodedata.normalize(
#                            'NFKD',contact.message).encode('ascii','ignore'))
#dmessage = (contact.message).encode('utf-8','ignore')
#dmessage = contact.message.decode("utf-8")
#dmessage = "%s" % dmessage
dmessage = contact.message

csv_writer.writerow([
        dmessage,
])

有没有人能给我一些建议,如何去除unicode字符,以便我可以导出到CSV?这个看似简单的问题让我感到困惑。非常感谢任何帮助。 谢谢, 乔

3 个回答

1

[注意:我不是Django专家;Django可能有更好的解决方案]

一般来说,不特定于Django的回答:

如果你有一些已知的非ASCII字符,并且这些字符有用户可以接受的ASCII替代品,你可以建立一个翻译表,然后使用unicode.translate这个方法:

smashcii = {
    0x2019 : u"'",
    # etc
    #

smashed = input_string.translate(smashcii)
2

编码真让人头疼,不过如果你在用django的话,有没有试过 smart_unicode(str) 这个函数,它在 django.utils.encoding 里?我发现这个通常能解决问题。

我找到的另一个选择就是用python自带的 encode()decode() 来处理字符串,不过你得自己指定编码,老实说,这也挺麻烦的。

7

你不能把Unicode字符 u'\u2019'(U+2019 右单引号)编码成ASCII,因为ASCII里没有这个字符。ASCII只包含基本的拉丁字母、数字和标点符号;它不支持带重音的字母或者像这个字符这样的“智能引号”。

所以你需要选择另一种编码方式。通常情况下,最合理的做法是使用UTF-8编码,因为它可以包含任何Unicode字符。不幸的是,如果你的目标用户使用的是Office(他们很可能是),那么他们在CSV文件中是无法读取UTF-8编码的字符的。Excel会根据那台机器的系统默认编码来读取文件(这个编码也被误称为“ANSI”编码),结果就会出现像 ’ 这样的乱码,而不是

这就意味着,如果你想让字符正确显示,你必须猜测用户的系统默认编码。对于西方用户来说,这个编码是1252。使用非西方Windows系统的用户可能会看到错误的字符,但对此你无能为力(除了组织一场写信运动,要求微软干脆放弃这个无聊的ANSI编码,像其他人一样使用UTF-8)。

编码1252可以包含U+2019(),但显然还有很多其他字符是它无法表示的。为了避免出现 UnicodeEncodeError 错误,你可以使用 ignore 参数(或者用 replace 把它们替换成问号)。

dmessage= contact.message.encode('cp1252', 'ignore')

或者,你也可以选择放弃,删除所有非ASCII字符,这样无论用户来自哪个地区,大家的体验都一样糟糕:

dmessage= contact.message.encode('ascii', 'ignore')

撰写回答