【问题标题】:Unicode Decode Error when trying to read csv file in python尝试在 python 中读取 csv 文件时出现 Unicode 解码错误
【发布时间】:2017-08-01 08:16:47
【问题描述】:

我是 python 和 stackoverflow 的新手。

  • 我有一个包含 csv 文件的文件夹,我正在尝试从每个文件中读取字段名称并将它们写入新的 csv 文件。
  • 感谢 stackoverflow,我能够制作和编辑我的代码,直到出现 unicode 错误。
  • 我尽了最大努力解决这个错误并进行了研究。
  • 我发现在 Mac 或 Linux 中创建的文件具有 utf8 unicode,而在 Windows 中创建的文件具有 cp949。
  • 因此,我必须用 utf8 打开它们。

我的代码最初看起来像这样:

import csv
import glob
lst=[]
files=glob.glob('C:/dataset/*.csv')
with open('test.csv','w',encoding='cp949',newline='') as testfile:
    csv_writer=csv.writer(testfile)
    for file in files:
        with open(file,'r') as infile:
            file=file[file.rfind('\\')+1:]
            reader=csv.reader(infile)
            headers=next(reader) 
            headers=[str for str in headers if str] 
            while len(headers) < 3 :
                headers=next(reader) 
                headers=[str for str in headers if str]
            lst=[file]+headers
            csv_writer.writerow(lst)

然后这个错误就出来了:

Traceback (most recent call last):
  File "C:\Python35\2.py", line 12, in <module>
    headers=next(reader)
UnicodeDecodeError: 'cp949' codec can't decode byte 0xec in position 6: illegal multibyte sequence

这是我尝试修复 unicode 错误的方法:

import csv
import glob
lst=[]
files=glob.glob('C:/dataset/*.csv')
with open('test.csv','w',encoding='cp949',newline='') as testfile:
    csv_writer=csv.writer(testfile)
    for file in files:
        try:
            with open(file,'r') as infile:
                file=file[file.rfind('\\')+1:]
                reader=csv.reader(infile)
                headers=next(reader) 
                headers=[str for str in headers if str] 
                while len(headers) < 3 :
                    headers=next(reader) 
                    headers=[str for str in headers if str]
                lst=[file]+headers
                csv_writer.writerow(lst)
        except:
            with open(file,'r',encoding='utf8') as infile:
                file=file[file.rfind('\\')+1:]
                reader=csv.reader(infile)
                headers=next(reader)
                headers=[str for str in headers if str]
                while len(headers) < 3 :
                    headers=next(reader) 
                    headers=[str for str in headers if str]
                lst=[file]+headers
                csv_writer.writerow(lst)

然后这个错误就出来了:

Traceback (most recent call last):
  File "C:\Python35\2.py", line 12, in <module>
    headers=next(reader)
UnicodeDecodeError: 'cp949' codec can't decode byte 0xec in position 6: illegal multibyte sequence

在处理上述异常的过程中,又发生了一个异常:

Traceback (most recent call last):
  File "C:\Python35\2.py", line 20, in <module>
    with open(file,'r',encoding='utf8') as infile:
FileNotFoundError: [Errno 2] No such file or directory: '2010_1_1.csv'

文件'2010_1_1.csv'肯定存在于我的目录('C:/dataset/*.csv')

当我尝试使用 open('C:/dataset/2010_1_1.csv','r',encoding='utf8') 单独打开此文件时,它可以工作,但文件名旁边有 '\ufeff'。

我不确定,但我的猜测是该文件正在try: 中打开并且尚未关闭,因此 python 无法在except 中打开此文件。

如何编辑我的代码来解决这个 Unicode 问题?


import glob
from chardet.universaldetector import UniversalDetector
files=glob.glob('C:/example/*.csv')
for filename in files:
print(filename.ljust(60)),
detector.reset()
for line in file(filename, 'rb'):
    detector.feed(line)
    if detector.done: break
detector.close()
print(detector.result)

错误:

Traceback (most recent call last):
  File "<pyshell#20>", line 4, in <module>
    for line in file(filename, 'rb'):
TypeError: 'str' object is not callable

【问题讨论】:

  • 这个格式很差。
  • @Nabin 对不起.. 我尽力了,但我的代码和我的问题都很混乱。
  • 对于file not found 错误,您确定您的代码以C:/dataset/ 作为其工作目录运行吗?您可以使用os.getcwd() 来查找。我不确定编码。
  • @Stael 是的。由于它适用于 670 个文件,因此我的代码使用 C:/dataset/ 运行。
  • 通常情况下,上下文管理器 (with) 应该在进入 except 块之前关闭文件。但我无法理解您所说的它有效但文件名旁边有'\ufeff' 是什么意思。您能否详细说明一下,因为我怀疑这是您问题的关键('\ufeff' 是 unicode 字节顺序标记)

标签: python csv unicode utf-8


【解决方案1】:

我对 Python 不是很熟悉,因此无法将我叫出来,但您可以在打开文件时尝试忽略文件的编码。我是一名 Java 程序员,根据我的经验,只需要在创建新文件时指定编码,而不是在打开文件时指定。

【讨论】:

  • 感谢您的意见。但事情是,正如我上面提到的,当我单独做时它会起作用。如果每次我的代码停止时都手动检查它们,我不知道哪些文件会导致错误。当我想使用tryexcept 一次完成这项工作时,它就不起作用了。
【解决方案2】:

如果无法正确解码,您的文件似乎不是用cp949 编写的。您必须找出正确的编码。像 chardet 这样的模块可以提供帮助。

在 Windows 上,读取文件时使用写入的编码打开它。如果是 UTF-8,请使用 utf-8-sig,它会自动处理并删除字节顺序标记 (BOM) U+FEFF 字符当下。编写时,最好的办法是使用utf-8-sig,因为它处理所有可能的 Unicode 字符并将添加 BOM,因此记事本和 Excel 等 Windows 工具将识别 UTF-8 编码的文件。如果没有它,大多数 Windows 工具将采用 ANSI 编码,这会因 Windows 的本地化版本而异。

【讨论】:

  • 我尝试使用open 检查文件的编码,结果是所有文件的编码都是cp949,这很奇怪。当我通过在 excel 上手动打开导致错误的 csv 文件检查它们时,它们的格式与那些有效的文件不同。例如,如果 (1,2) 是 NAME,则第 2 列的每一行都应该是 NAME,但在某些行中,不是将多个名称放在一个单元格 (column2) 中,而是将每个名称记录在从 2 到任何列的每一列中,因此行的长度彼此不同。
  • 我会尝试 chardet 再次检查编码。
  • open 不检测编码,这只是您系统上的默认设置。您必须知道正在打开的文件的正确编码。
  • 哦!好的。我会试试chardet
  • 我编辑了我的问题以上传尝试 chardet 的代码。我不应该这样做吗?
【解决方案3】:

错误以 Unicode 解码错误的形式出现例如:>json、xml、csv....

陷入此问题的唯一避免方法是通过在 open() 中使用 errors='ignore' 参数忽略代码第一部分中的解码错误:>

       with open('test.csv','w',encoding='cp949',newline='') as testfile:

#to         

       with open(r'test.csv','w',encoding='cp949',newline='',errors='ignore') as testfile:
                                    #or
            data = open(r'test.csv',errors='ignore').read()#read the file as a data 

如果错误仍然存​​在,则使用 errors='ignore' 对不同的编码进行检查

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-06-09
    • 2019-01-23
    • 2015-02-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多