【问题标题】:How to address: Python import of file with .csv Dictreader fails on undefined character如何解决:使用 .csv Dictreader 导入文件的 Python 在未定义字符上失败
【发布时间】:2019-02-04 19:40:25
【问题描述】:

首先,我找到the following,这与我的问题基本相同,但它已关闭,我不确定我是否理解关闭的原因与帖子的内容。我也没有真正看到有效的答案。

我有来自 4 个应用程序的 20 多个输入文件。所有文件都导出为 .csv 文件。前 19 个文件有效(从同一个应用程序导出的另外 4 个文件有效),然后我遇到了一个给我这个错误的文件:

UnicodeDecodeError: 'charmap' codec can't decode byte 0x8f in position 5762: character maps to <undefined>

如果我向上看,它是一个 &lt ctrl &gt。下面的代码是相关行:

with open(file, newline = '') as f: 
    reader = csv.DictReader(f, dialect = 'excel')
    for line in reader:

我知道我会得到一个文件。我知道这将是一个 .csv。由于源文件的手动生成/导出,我得到的结果可能会有所不同。某些文件中可能还存在一些奇怪的字符(例如日文、俄文等)。我提供此信息是因为返回源代码以获取不同的文件可能只会在我必须提取更新的数据(或者更糟,其他人这样做)之前将罐子踢掉。

所以这个问题可能是多方面的:
1)有没有办法告诉 csv.DictReader 忽略未定义的字符? (对编解码器的提示:如果我看不到它,它对我来说毫无价值。)

2) 如果我确实有“疯狂”的角色,我该怎么办?我考虑过将每个输入作为二进制文件打开,过滤掉有问题的十六进制字符,将文件写回磁盘,然后打开新文件,但这对程序来说似乎有很多开销,对我来说甚至更多。这也是 1977 年的一些 JCL 声明。

3) 如果我在阅读时崩溃,我如何确定我得到了什么作为输入。

4)我选择了“方言='excel'”;因为许多输入是可以从源应用程序之一下载的 Excel 文件。从 dictreader 上的文档来看,我的印象是这只是定义了分隔符、引号字符和 EOL 字符以期望/使用。因此,我不认为这是我的问题,但我也是 Python 菜鸟,所以我不是 100% 确定。

【问题讨论】:

  • 当环境以 ASCII 编码读取文件时,通常会出现此问题,而文件实际上是 UTF-8(这很可能是因为您的 CSV 中有非英语语言字符)。尝试更新代码以指定文本编码:with open(file, newline = '', encoding = 'utf8') as f:
  • 不幸的是它没有用。刚刚收到一条不同的消息:UnicodeDecodeError: 'utf-8' codec can't decode byte 0x96 in position 197: invalid start byte
  • 我回到源文件并在 Excel 中打开它。我对 .csv 类型(不是 unicode 类型)进行了“另存为”。它已经设置为该文件格式,因此可以回答它是否是 Unicode。问题在于数据来自一个发现工具,该工具可以从全球数千台设备中提取数据。所以源文件中确实可能有奇怪的东西
  • 找到了答案。根据反馈,我决定查看是否有其他我应该尝试的编解码器。在查看文档时,我发现 open errors='strict' 中有一个参数。它实际上并没有说明其他选项是什么,但这导致了正确的谷歌搜索。该线程是重复的,但不是上面引用的线程。正确的答案是用errors='ignore'打开文件。这解决了问题。这是解决方案的线程:stackoverflow.com/questions/10487563/…

标签: python python-3.x file csv


【解决方案1】:

我在上面的 cmets 中发布了我使用的解决方案;就是将open()errors参数设置为'ignore'

with open(file, newline = '', errors='ignore') as f: 

这正是我在上面原始帖子的第一个问题中所寻找的(即是否有办法告诉csv.DictReader 忽略未定义的字符)。

更新:后来我确实需要处理一些 Unicode 字符并且无法忽略它们。基于 Excel 生成的 unicode .csv 文件的该解决方案的正确答案是使用“utf_8_sig”编解码器。这将删除 Windows 在文件顶部写入的字节顺序标记(utf-16 BOM),以使其知道其中有 unicode 字符。

【讨论】:

    猜你喜欢
    • 2016-03-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-17
    • 1970-01-01
    • 2016-04-06
    • 2017-11-19
    相关资源
    最近更新 更多