【问题标题】:Python 3 CSV file giving UnicodeDecodeError: 'utf-8' codec can't decode byte error when I printPython 3 CSV 文件给出 UnicodeDecodeError: 'utf-8' codec can't decode byte error when I print
【发布时间】:2014-02-25 13:53:55
【问题描述】:

我在 Python 3 中有以下代码,用于打印 csv 文件中的每一行。

import csv
with open('my_file.csv', 'r', newline='') as csvfile:
    lines = csv.reader(csvfile, delimiter = ',', quotechar = '|')
    for line in lines:
        print(' '.join(line))

但是当我运行它时,它给了我这个错误:

UnicodeDecodeError: 'utf-8' codec can't decode byte 0x96 in position 7386: invalid start byte

我查看了 csv 文件,结果发现如果我取出一个 ñ(顶部有波浪号的小 n),每一行都可以打印出来。

我的问题是,我已经查看了一堆针对类似问题的不同解决方案,但我仍然不知道如何解决这个问题,解码/编码什么等。只需取出数据中的 ñ 字符即可不是一个选项。

【问题讨论】:

  • 你能分享你的csv文件的一行有ñ。

标签: python csv python-3.x encoding utf-8


【解决方案1】:

我们知道该文件包含字节b'\x96',因为它在错误消息中提到:

UnicodeDecodeError: 'utf-8' codec can't decode byte 0x96 in position 7386: invalid start byte

现在我们可以编写一个小脚本来查看是否有任何编码将b'\x96' 解码为ñ

import pkgutil
import encodings
import os

def all_encodings():
    modnames = set([modname for importer, modname, ispkg in pkgutil.walk_packages(
        path=[os.path.dirname(encodings.__file__)], prefix='')])
    aliases = set(encodings.aliases.aliases.values())
    return modnames.union(aliases)

text = b'\x96'
for enc in all_encodings():
    try:
        msg = text.decode(enc)
    except Exception:
        continue
    if msg == 'ñ':
        print('Decoding {t} with {enc} is {m}'.format(t=text, enc=enc, m=msg))

产生

Decoding b'\x96' with mac_roman is ñ
Decoding b'\x96' with mac_farsi is ñ
Decoding b'\x96' with mac_croatian is ñ
Decoding b'\x96' with mac_arabic is ñ
Decoding b'\x96' with mac_romanian is ñ
Decoding b'\x96' with mac_iceland is ñ
Decoding b'\x96' with mac_turkish is ñ

因此,请尝试更改

with open('my_file.csv', 'r', newline='') as csvfile:

到其中一种编码,例如:

with open('my_file.csv', 'r', encoding='mac_roman', newline='') as csvfile:

【讨论】:

  • 它对我有用,但为什么使用 mac_roman 而不是 utf-8 作为编码?
  • 很好的答案,即使我必须解决 mac_roman 编码的问题。
  • 很好的解释!
【解决方案2】:

with open('my_file.csv', 'r', newline='', encoding='ISO-8859-1') as csvfile:

ñ 字符未在 UTC-8 编码中列出。要解决此问题,您可以改用 ISO-8859-1 编码。有关此编码的更多详细信息,您可以参考以下链接: https://www.ic.unicamp.br/~stolfi/EXPORT/www/ISO-8859-1-Encoding.html

【讨论】:

    【解决方案3】:

    对于遇到主题中显示的相同错误的其他人,请注意您的 csv 文件的文件编码。它可能不是utf-8。我刚刚注意到 LibreOffice 今天为我创建了一个 utf-16 编码的文件,但没有提示我,尽管我无法重现它。

    如果你尝试使用open(... encoding='utf-8')打开一个utf-16编码的文档,你会得到错误:

    UnicodeDecodeError: 'utf-8' 编解码器无法在位置解码字节 0xff 0:无效的起始字节

    修复指定 'utf-16' 编码或更改 csv 的编码。

    【讨论】:

    • 我遇到了这个确切的问题。拔掉头发后,我发现了这个建议。 FWIW,如果您使用 Excel 2013+,请将文件另存为“CSV (MS DOS)”
    • +1 是的,这是一个常见的问题。对于 CSV 文件,如果 Excel 使用某些您不想要的 'utf-16' 编码保存了文件,那么 即使您删除了有问题的 unicode 字符,您也要确保文件格式为 ' CSV UTF-8(逗号分隔)(.csv)' 保存时(或“另存为”)。
    【解决方案4】:

    我也遇到了 python 3 的问题,使用编码类型 utf-16

    解决了我的问题
    with open('data.csv', newline='',encoding='utf-16') as csvfile:
    

    【讨论】:

      【解决方案5】:

      简单...只需在 Excel 或 OpenOffice calc 中打开它,使用文本作为列,选择,,然后将文件另存为.csv...我花了一天几小时的时间搜索谷歌...但最后我想通了。

      【讨论】:

        【解决方案6】:

        只需为可能包含字符而不是英文字符的文件尝试 UTF-16,这就是为其实施 UTF-16 的原因。 8 和 16 实现是相同的 unicode,但唯一的区别是位数,因此 16 将处理像 ~ 这样的字符,而 8 不会,只是 a-zA-Z0-9 字符

        with open('my_file.csv', 'r', newline='', encoding='UTF-16') as csvfile:
        

        【讨论】:

          【解决方案7】:

          一个更简单的解决方案是在记事本中打开 csv 文件,然后在“文件”下拉列表中选择“另存为”。选择“保存类型”到“所有文件(.)”。在编码下拉列表中选择“UTF-8 编码”,并将“.csv”扩展名添加到文件名

          【讨论】:

            【解决方案8】:
            with open('my_file.csv', 'r', newline='', encoding='utf-8') as csvfile:
            

            尝试像上面那样打开文件

            【讨论】:

            • 这不起作用,因为错误消息表明它已经在尝试使用 UTF-8 编解码器。
            • ..虽然另一种编码可能会起作用。就我而言,latin-1 完成了这项工作
            • 我不明白为什么这个答案有反对意见。设置正确的文件编码已经彻底解决了这个问题。
            猜你喜欢
            • 1970-01-01
            • 2020-01-31
            • 1970-01-01
            • 2013-11-11
            • 2022-01-13
            • 1970-01-01
            • 2018-05-21
            • 2020-05-08
            相关资源
            最近更新 更多