【问题标题】:Unicode decode error with .csv file.csv 文件的 Unicode 解码错误
【发布时间】:2015-09-01 12:24:47
【问题描述】:

我有一个可能是一个非常基本的 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 创建的,如果有帮助的话。

【问题讨论】:

    标签: python csv python-3.x unicode codec


    【解决方案1】:

    也许您可以尝试遍历崩溃的 csv 文件,例如:

    with open(file) as f:
        for line in f:
            print repr(line)
    

    查看是否有任何可疑字符弹出。

    如果您能够以这种方式识别可疑字符,例如弹出 \0Xý1,您可以通过重写和替换该字符来清理文件:

    with open(file) as f:
        with open(file.rstrip(".csv") + "_fixed.csv") as g:
            for line in f:
                g.write(line.replace('\0Xý1', ''))
    

    然后使用已清理的文件重试。

    【讨论】:

      【解决方案2】:

      这是一个编码问题。输入 csv 文件不是您的 Python 平台所期望的 utf-8 编码。问题是不知道它的编码,也没有一个违规行的例子,我真的猜不出编码。

      encoding='utf8'encoding='ascii' 都被破坏是正常的,因为违规字符是 0xa2,它不在 ascii 范围内 (encoding='latin1' 在同一个地方给出同样的错误真的很奇怪,因为 0xa2 在 latin1 中是 ¢

      恕我直言,根据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') 得到它)

      那么你就可以在这里发布违规行了

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-04-24
        • 1970-01-01
        • 1970-01-01
        • 2017-06-03
        • 1970-01-01
        • 2021-09-01
        相关资源
        最近更新 更多