网络上有很多关于这个问题的主题,但我似乎无法找到具体案例的答案。
我有一个CSV文件。我不确定它是做了什么,但当我试图打开它时,我得到:
UnicodeDecodeError:'utf8'编解码器无法解码位置0的字节0xff:无效的起始字节
这是一个完整的Traceback
:
Traceback (most recent call last):
File "keywords.py", line 31, in <module>
main()
File "keywords.py", line 28, in main
get_csv(file_full_path)
File "keywords.py", line 19, in get_csv
for row in reader:
UnicodeEncodeError: 'ascii' codec can't encode character u'\u5a07' in position 10: ordinal not in range(128)
在Stack Overflow的帮助下,我打开了:
reader = csv.reader(codecs.open(file_full_path, 'rU', 'UTF-16'), delimiter='\t', quotechar='"')
现在的问题是,当我正在阅读文件时:
def get_csv(file_full_path):
import csv, codecs
reader = csv.reader(codecs.open(file_full_path, 'rU', 'UTF-16'), delimiter='\t', quotechar='"')
for row in reader:
print row
我被困在亚洲符号上:
UnicodeEncodeError:'ascii'编解码器无法对位置10中的字符u'\ u5a07'进行编码:序数不在范围内(128)
我在包含该字符的字符串上尝试了decode
,'encode',unicode()
,但似乎没有帮助。
for row in reader:
#decoded_row = [element_s.decode('UTF-8') for element_s in row]
#print decoded_row
encoded_row = [element_s.encode('UTF-8') for element_s in row]
print encoded_row
此时我并不理解为什么。如果我
>>> print u'\u5a07'
娇
或
>>> print '娇'
娇
它有效。也在终端,它也有效。我检查了终端和Python shell的默认编码,到处都是UTF-8。它很容易打印出这个符号。我假设它与我用codecs
使用UTF-16打开文件有关。
我不知道从哪里开始。有人可以帮忙吗?
答案 0 :(得分:3)
csv
模块无法处理Unicode输入。它在documentation page上具体说明了:
注意:此版本的
csv
模块不支持Unicode输入。此外,目前有一些关于ASCII NUL字符的问题。因此,所有输入应为UTF-8或可打印的ASCII以确保安全;
您需要将CSV文件转换为UTF-8,以便模块可以处理它:
with codecs.open(file_full_path, 'rU', 'UTF-16') as infile:
with open(file_full_path + '.utf8', 'wb') as outfile:
for line in infile:
outfile.write(line.encode('utf8'))
或者,您可以使用命令行实用程序iconv
为您转换文件。
然后使用该重新编码的文件来读取您的数据:
reader = csv.reader(open(file_full_path + '.utf8', 'rb'), delimiter='\t', quotechar='"')
for row in reader:
print [c.decode('utf8') for c in row]
请注意,这些列需要手动解码为unicode。
答案 1 :(得分:-1)
当您尝试将unicode字符转换为8位序列时,会出现编码错误。因此,当实际读取文件时,您的第一个错误不是错误获取,但稍后。
您可能会收到此错误,因为Python 2 CSV模块希望文件处于二进制模式,而您打开它时会返回unicode字符串。
将您的开场改为:
reader = csv.reader(open(file_full_path, 'rb'), delimiter='\t', quotechar='"')
你应该没事。甚至更好:
with open(file_full_path, 'rb') as infile:
reader = csv.reader(infile, delimiter='\t', quotechar='"')
# CVS handling here.
但是,您不能使用UTF-16(或UTF-32),因为分隔字符是UTF-16中的双字节字符,并且它无法正确处理,因此您需要将其转换为首先是UTF-8。