"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
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