我是csv.reader从很长的表单中提取信息。我正在对该数据集进行工作,然后我使用xlwt包给我一个可行的excel文件。
然而,我收到此错误:
UnicodeDecodeError:'ascii'编解码器无法解码位置34的字节0x92:序号不在范围内(128)
我的问题是,我怎样才能找到该数据集中错误的确切位置?另外,是否有一些我可以编写的代码可以查看我的数据集并找出问题所在(因为某些数据集运行时没有出现上述错误而其他数据集存在问题)?
答案 0 :(得分:3)
实际上答案非常简单:只要从文件中读取数据,就可以使用文件的编码将其转换为unicode,并处理UnicodeDecodeError异常:
try:
# decode using utf-8 (use ascii if you want)
unicode_data = str_data.decode("utf-8")
except UnicodeDecodeError, e:
print "The error is there !"
这将使你免于许多麻烦;你不必担心多字节字符编码,外部库(包括xlwt)如果需要编写就会做正确的事情。
Python 3.0将强制指定字符串的编码,因此现在最好这样做。
答案 1 :(得分:1)
csv
模块不支持unicode和null字符。您可以通过执行类似的操作来替换它们(将'utf-8'替换为编码CSV数据的编码):
import codecs
import csv
class AsciiFile:
def __init__(self, path):
self.f = codecs.open(path, 'rb', 'utf-8')
def close(self):
self.f.close()
def __iter__(self):
for line in self.f:
# 'replace' for unicode characters -> ?, 'ignore' to ignore them
y = line.encode('ascii', 'replace')
y = y.replace('\0', '?') # Can't handle null characters!
yield y
f = AsciiFile(PATH)
r = csv.reader(f)
...
f.close()
如果您想找到CSV模块无法处理的字符位置,您可以这样做:
import codecs
lineno = 0
f = codecs.open(PATH, 'rb', 'utf-8')
for line in f:
for x, c in enumerate(line):
if not c.encode('ascii', 'ignore') or c == '\0':
print "Character ordinal %s line %s character %s is unicode or null!" % (ord(c), lineno, x)
lineno += 1
f.close()
或者,您可以再次使用我编写的CSV开头工具,它可以处理Unicode字符:
import codecs
def OpenCSV(Path, Encoding, Delims, StartAtRow, Qualifier, Errors):
infile = codecs.open(Path, "rb", Encoding, errors=Errors)
for Line in infile:
Line = Line.strip('\r\n')
if (StartAtRow - 1) and StartAtRow > 0: StartAtRow -= 1
elif Qualifier != '(None)':
# Take a note of the chars 'before' just
# in case of excel-style """ quoting.
cB41 = ''; cB42 = ''
L = ['']
qMode = False
for c in Line:
if c==Qualifier and c==cB41==cB42 and qMode:
# Triple qualifiers, so allow it with one
L[-1] = L[-1][:-2]
L[-1] += c
elif c==Qualifier:
# A qualifier, so reverse qual mode
qMode = not qMode
elif c in Delims and not qMode:
# Not in qual mode and delim
L.append('')
else:
# Nothing to see here, move along
L[-1] += c
cB42 = cB41
cB41 = c
yield L
else:
# There aren't any qualifiers.
cB41 = ''; cB42 = ''
L = ['']
for c in Line:
cB42 = cB41; cB41 = c
if c in Delims:
# Delim
L.append('')
else:
# Nothing to see here, move along
L[-1] += c
yield L
for listItem in openCSV(PATH, Encoding='utf-8', Delims=[','], StartAtRow=0, Qualifier='"', Errors='replace')
...
答案 2 :(得分:0)
您可以参考以下问题中的代码段来获取具有unicode编码支持的csv阅读器:
答案 3 :(得分:0)
请提供您收到的错误消息的完整回溯。当我们知道你在哪里得到错误(阅读CSV文件,“对该数据集进行工作”,或者使用xlwt编写XLS文件)时,我们可以给出一个有针对性的答案。
您的输入数据很可能不是所有普通的旧ASCII。什么产生它,以什么编码?
要找到问题(不一定是错误)的位置,请尝试这样的小脚本(未经测试):
import sys, glob
for pattern in sys.argv[1:]:
for filepath in glob.glob(pattern):
for linex, line in enumerate(open(filepath, 'r')):
if any(c >= '\x80' for c in line):
print "Non-ASCII in line %d of file %r" % (linex+1, filepath)
print repr(line)
如果您展示了一些您所找到的“坏”行的样本,那将非常有用,这样我们就可以判断编码可能是什么。
我很好奇使用“csv.reader从非常长的表格中提取信息” - 什么样的“表格”?您是说要将XLS文件保存为CSV,然后读取CSV文件?如果是这样,您可以使用 xlrd 直接从输入XLS文件中读取,获取可直接提供给xlwt
的unicode文本,从而避免任何编码/解码问题。
您是否已完成python-excel.org site的教程?