将Python命名元组写入CSV以防止Unicode编码错误
我正在使用py2neo从我的neo4j数据库导出数据。(我在MacOS X上使用Python 2.7)
这是我一直在用的代码:
import csv
from py2neo import neo4j, cypher, node, rel
import pprint
ofile = open('mydata.csv', 'wb')
writer = csv.writer(ofile, delimiter='\t', quotechar='|', quoting = csv.QUOTE_ALL)
graph_db = neo4j.GraphDatabaseService("http://xx.xx.xx.xx:7474/db/data/")
qs = '''MATCH (a:MyLabel)
WHERE NOT a.shortdesc = ""
RETURN a.name, a.shortdesc, a.longdesc
ORDER BY a.name'''
query = neo4j.CypherQuery(graph_db, qs)
writer.writerows(query.stream())
在属性a.shortdesc和a.longdesc中,明显有一些奇怪的字符,我搞不清楚该怎么正确编码它们。我遇到了这个错误:
UnicodeEncodeError: 'ascii' codec can't encode character u'\u201c' in position 148: ordinal not in range(128)
我尝试了各种不同的方法……我该如何处理这些命名元组,使它们能够正确编码,以便我可以写入一个csv文件呢?
1 个回答
4
你正在尝试写一些包含Unicode数据的内容,其中有一个叫做U+201C 左双引号的字符。
你需要把这些值编码成UTF-8格式,或者找到其他方法来表示这些Unicode值。
编码可以通过生成器表达式和列表推导式来完成,这样可以对每一列进行编码:
writer.writerows([unicode(c).encode('utf8') for c in row] for row in query.stream())
使用unicode()
这个函数可以确保在编码之前,非Unicode的值会先被转换成Unicode字符串。
你也可以尝试“简化”这些值;你找到的这个字符是一个“花哨”的引号,可能只是因为某个文字处理软件或电子表格应用把普通引号替换成了这种引号。如果你的数据其他部分都是普通的ASCII文本或数字,你可以尝试把这些“花哨”的字符替换成ASCII的对应字符。
可以使用Unidecode包来把这些字符替换成ASCII版本:
from unidecode import unidecode
writer.writerows([unidecode(unicode(c)) for c in row] for row in query.stream())