【问题标题】:"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

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

【问题讨论】:

标签: python python-3.x character-encoding


【解决方案1】:

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

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

【讨论】:

【解决方案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']。查看此答案了解详情:stackoverflow.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.stackoverflow.com/questions/297673/… ),并且确实严格遵守该规则。对于俄语问题,您可以使用 ru.stackoverflow.com ;)
      • @ThierryLathuille 这适用于英文内容,而不是非英文符号的问题。而且这不一定与其他语言有关,它可以是不同的 UTF-8 字符(例如,复选标记)。
      【解决方案13】:

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

      如果您的脚本在 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'):

        打印(行)

        【讨论】:

          猜你喜欢
          • 2022-01-13
          • 2020-12-26
          • 1970-01-01
          • 1970-01-01
          • 2021-11-24
          • 2018-10-15
          • 1970-01-01
          • 2021-12-04
          相关资源
          最近更新 更多