我有一个非常基本的Python问题。
我正在尝试编写一个脚本,消除了一些.csv文件中的大量空白行,而我编写的脚本对我的文件大约有90%起作用,但有几个会向我抛出以下错误:
Traceback (most recent call last):
File "/Users/stephensmith/Documents/Permits/deleterows.py", line 17, in <module>
deleteRow(file, "output/" + file)
File "/Users/stephensmith/Documents/Permits/deleterows.py", line 8, in deleteRow
for row in csv.reader(input):
File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/codecs.py", line 319, in decode
(result, consumed) = self._buffer_decode(data, self.errors, final)
File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/encodings/utf_8_sig.py", line 69, in _buffer_decode
return codecs.utf_8_decode(input, errors, final)
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xa2 in position 6540: invalid start byte
这是我的代码:
import csv
import os
def deleteRow(in_fnam, out_fnam):
input = open(in_fnam, 'r')
output = open(out_fnam, 'w')
writer = csv.writer(output)
for row in csv.reader(input):
if any(row):
writer.writerow(row)
input.close()
output.close()
for file in os.listdir("/Users/stephensmith/Documents/Permits/"):
print(file)
if file.endswith(".csv"):
deleteRow(file, "output/" + file)
我尝试在我的两个open()语句中添加encoding ='utf-8',='ascii'和='latin1',但没有运气。 :-(知道我做错了吗?.csv文件是用Excel for Mac 2011创建的,如果这有帮助的话。
答案 0 :(得分:0)
也许您可以尝试循环使用以下内容崩溃的csv文件:
UTC time 2015-Jun-16 15:45:16
Local Time 2015-Jun-16 21:15:16
查看是否有任何可疑字符弹出。
如果您能够以这种方式识别可疑字符,请弹出 \0Xý1,您可以通过重写和替换该字符来清理文件:
with open(file) as f:
for line in f:
print repr(line)
然后再次使用已清理的文件。
答案 1 :(得分:0)
这是一个编码问题。输入csv文件不是像Python平台所期望的那样进行utf-8编码。问题是,如果不知道它的编码,也没有一个违规行的例子,我真的无法猜测编码。
encoding='utf8'
和encoding='ascii'
都是正常的,因为违规字符是0xa2,不在ascii范围内(&lt; = 0x7f)而不是有效的utf-8字符。但是encoding='latin1'
在同一个地方给出相同的错误真是奇怪,因为在latin1中0xa2是¢
。
恕我直言,根据this other SO post,您可以尝试encoding='windows-1252'
,如果您的平台支持它。
如果仍然无效,您应该尝试识别latin1
的违规行:
class special_opener:
def __init__(self, filename, encoding):
self.fd = open(filename, 'rb')
self.encoding = encoding
def __enter__(self):
return self
def __exit__(self, exc_type, exc_value, traceback):
return False
def __next__(self):
line = next(self.fd)
try:
return line.decode(self.encoding).strip('\r\n') + '\n'
except Exception as e:
print("Offending line : ", line, file = sys.stderr)
raise e
def __iter__(self):
return self
def deleteRow(in_fnam, out_fnam):
input = special_opener(in_fnam, 'latin1')
output = open(out_fnam, 'w')
writer = csv.writer(output)
for row in csv.reader(input):
if any(row):
writer.writerow(row)
input.close()
output.close()
special_opener
应该输出如下内容:
Offending line : b'a,\xe9,\xe8,d\r\n'
Traceback (most recent call last):
...
(此行有效latin1,我使用special_opener(file, 'utf8')
)
然后你就可以在这里发布违规行了