"for line in..." 导致 UnicodeDecodeError: 'utf-8' codec can't decode byte

Posted

技术标签:

【中文标题】"for line in..." 导致 UnicodeDecodeError: \'utf-8\' codec can\'t decode byte【英文标题】:"for line in..." results in UnicodeDecodeError: 'utf-8' codec can't decode byte"for line in..." 导致 UnicodeDecodeError: 'utf-8' codec can't decode byte 【发布时间】:2013-11-11 00:53:00 【问题描述】:

这是我的代码,

for line in open('u.item'):
# Read each line

每当我运行此代码时,都会出现以下错误:

UnicodeDecodeError: 'utf-8' codec can't decode byte 0xe9 in position 2892: invalid continuation byte

我试图解决这个问题并在 open() 中添加一个额外的参数。代码如下:

for line in open('u.item', encoding='utf-8'):
# Read each line

但它又给出了同样的错误。那我该怎么办?

【问题讨论】:

我认为数据编码错误。 或者只是不是 UTF-8 数据。 Python 3 UnicodeDecodeError - How do I debug UnicodeDecodeError?的可能重复 在使用 python 3 而不是 python 2.7 时,我们在 msgpack 中遇到了这个错误。对我们来说,行动方案是使用 python 2.7。 【参考方案1】:

您的文件实际上并不包含 UTF-8 编码的数据;它包含一些其他编码。弄清楚该编码是什么,并在open 调用中使用它。

例如,在Windows-1252 编码中,0xe9 将是字符é

【讨论】:

那么,我怎样才能知道它是什么编码!我正在使用 linux 没有办法做到始终有效,但请参阅此问题的答案:***.com/questions/436220/…【参考方案2】:

作为suggested by Mark Ransom,我找到了解决该问题的正确编码。编码为"ISO-8859-1",因此将open("u.item", encoding="utf-8") 替换为open('u.item', encoding = "ISO-8859-1") 即可解决问题。

【讨论】:

显式优于隐式 (PEP 20)。 诀窍在于 ISO-8859-1 或 Latin_1 是 8 位字符集,因此所有垃圾都有一个有效值。也许不可用,但如果你想忽略! 我遇到了同样的问题 UnicodeDecodeError: 'utf-8' codec can't decode byte 0xd0 in position 32: invalid continuation byte。我使用 python 3.6.5 安装 aws cli。当我尝试 aws --version 它失败并出现此错误。所以我不得不编辑 /Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/configparser.py 并将代码更改为以下 def read(self, filenames, encoding="ISO-8859 -1"): 有自动检测编码的方法吗? @OrangeSherbet 我使用chardet 实现了检测。这是一条线(在import chardet 之后):chardet.detect(open(in_file, 'rb').read())['encoding']。查看此答案了解详情:***.com/a/3323810/615422【参考方案3】:

这是在 Python 3 中转换 CSV 文件的示例:

try:
    inputReader = csv.reader(open(argv[1], encoding='ISO-8859-1'), delimiter=',',quotechar='"')
except IOError:
    pass

【讨论】:

【参考方案4】:

尝试使用Pandas阅读:

pd.read_csv('u.item', sep='|', names=m_cols, encoding='latin-1')

【讨论】:

不知道你为什么推荐 Pandas。解决方案是设置正确的编码,您在这里碰巧遇到过。 'latin-1' 和 'ISO-8859-1' 一样吗? @PeterMortensen 是的,Wikipedia confirms it。在 Python 中与 decode 一起使用时,它们都会产生相同的输出。【参考方案5】:

如果您使用的是 Python 2,以下将是解决方案:

import io
for line in io.open("u.item", encoding="ISO-8859-1"):
    # Do something

由于encoding 参数不适用于open(),您将收到以下错误:

TypeError: 'encoding' 是该函数的无效关键字参数

【讨论】:

但这是第 3 版 是的,我知道。我认为这可能对使用 Python 2 的人有所帮助 在 Python3 中也为我工作 如果您想要更容易记住的内容,'ISO-8859-1' 也称为'latin-1''latin1'【参考方案6】:

以下内容也对我有用。 ISO 8859-1 会节省很多,主要是如果使用语音识别 API。

例子:

file = open('../Resources/' + filename, 'r', encoding="ISO-8859-1")

【讨论】:

您可能是正确的,OP 正在读取 ISO 8859-1,这可以从错误消息中的 0xe9 (é) 中推断出来,但您应该解释为什么您的解决方案有效。对语音识别 API 的引用没有帮助。【参考方案7】:

有时当使用open(filepath)filepath实际上不是一个文件时会得到同样的错误,所以首先确保你要打开的文件存在:

import os
assert os.path.isfile(filepath)

【讨论】:

如何打开一个不存在的文件生成UnicodeDecodeError?在 Python 中,习惯上使用 the EAFP principle 代替您在此处认可的 LBYL。【参考方案8】:

您可以通过以下方式解决问题:

for line in open(your_file_path, 'rb'):

'rb' 正在以二进制模式读取文件。阅读更多here。

【讨论】:

【参考方案9】:

这行得通:

open('filename', encoding='latin-1')

或者:

open('filename', encoding="ISO-8859-1")

【讨论】:

取决于“作品”的含义。如果您的意思是避免异常,那是正确的,因为它是唯一没有无效字节或序列的编码。但这并不意味着你会得到正确的字符。【参考方案10】:

你可以试试这个方法:

open('u.item', encoding='utf8', errors='ignore')

【讨论】:

这没有提供问题的答案。要批评或要求作者澄清,请在他们的帖子下方留下评论。 - From Review @MartenCatcher 是的,但它可以帮助未来的访问者解决这个问题,尽管对答案进行更多解释会使它变得更好,但我相信它作为答案而不是作为评论更有用 目的是什么?忽略错误?有什么后果?【参考方案11】:

使用Notepad++ 打开您的文件,选择“编码”或“编码”菜单以识别或从 ANSI 转换为 UTF-8 或ISO 8859-1 代码页。

【讨论】:

Notepad++ 仅适用于 Windows。例如,它不适用于Linux。 什么是“编码”?什么语言?【参考方案12】:

为了在类似问题(关于 UTF-8 错误)上更快地搜索网页,我将我的解决方案留给其他人。

我在打开带有该描述的 .csv 文件时遇到了问题:

UnicodeDecodeError: 'utf-8' codec can't decode byte 0xe9 in position 150: invalid continuation byte

我用记事本打开文件并计算到第 150 位:那是一个西里尔符号。 我使用编码为“UTF-8”的“另存为..”命令重新保存了该文件,并且我的程序开始工作。

【讨论】:

请注意,关于 SO 的问题和答案必须仅使用英文 - 即使您遇到的问题可能主要针对使用西里尔字母的程序员 @ThierryLathuille,这是一个真正的问题吗?您能否给我一个链接/参考关于该问题的社区规则? 这被认为是一个真正的问题 - 并且可能是导致您的答案被否决的原因。 SO 上不允许使用非英语内容(例如参见 meta.***.com/questions/297673/… ),并且确实严格遵守该规则。对于俄语问题,您可以使用 ru.***.com ;) @ThierryLathuille 这适用于英文内容,而不是非英文符号的问题。而且这不一定与其他语言有关,它可以是不同的 UTF-8 字符(例如,复选标记)。【参考方案13】:

根据another question on *** 和本文之前的答案,我想添加帮助以找到正确的编码。

如果您的脚本在 Linux 操作系统上运行,您可以使用 file 命令获取编码:

file --mime-encoding <filename>

这里有一个 python 脚本可以为你做到这一点:

import sys
import subprocess

if len(sys.argv) < 2:
    print("Usage:  <filename>".format(sys.argv[0]))
    sys.exit(1)

def find_encoding(fname):
    """Find the encoding of a file using file command
    """

    # find fullname of file command
    which_run = subprocess.run(['which', 'file'], stdout=subprocess.PIPE)
    if which_run.returncode != 0:
        print("Unable to find 'file' command ()".format(which_run.returncode))
        return None

    file_cmd = which_run.stdout.decode().replace('\n', '')

    # run file command to get MIME encoding
    file_run = subprocess.run([file_cmd, '--mime-encoding', fname],
                               stdout=subprocess.PIPE,
                               stderr=subprocess.PIPE)
    if file_run.returncode != 0:
        print(file_run.stderr.decode(), file=sys.stderr)

    # return  encoding name only
    return file_run.stdout.decode().split()[1]

# test
print("Encoding of : ".format(sys.argv[1], find_encoding(sys.argv[1])))

【讨论】:

我一直在寻找答案,有趣的是,您在 7 小时前回答了 8 年前提出的问题。有趣的巧合。 我不明白,为什么要使用 33 行的程序来避免在 shell 中键入一行?【参考方案14】:

我正在使用从Kaggle 下载的数据集,同时读取此数据集时抛出此错误:

UnicodeDecodeError: 'utf-8' 编解码器无法在位置解码字节 0xf1 183: 无效的继续字节

所以这就是我修复它的方法。

import pandas as pd

pd.read_csv('top50.csv', encoding='ISO-8859-1')

【讨论】:

【参考方案15】:

编码替换为 encoding='ISO-8859-1'

for line in open('u.item', encoding='ISO-8859-1'):

打印(行)

【讨论】:

以上是关于"for line in..." 导致 UnicodeDecodeError: 'utf-8' codec can't decode byte的主要内容,如果未能解决你的问题,请参考以下文章

Python C 程序子进程在“for line in iter”处挂起

"Installation failed !" in GUI but not in CLI (/usr/bin/winusb: line 78: 18265 Terminated

python按行读取文件,如何去掉换行符" "

EParseError Unrecognized parameter name "Type" on line 592 in Aeston

laravel报错,NotFoundHttpException in RouteCollection.php line 161:

/usr/lib/python2.7/subprocess.py", line 1239, in _execute_child