UnicodeDecodeError:“utf-8”编解码器无法解码位置 173310 中的字节 0xb3:起始字节无效

jas*_*spu 1 python git unicode utf-8 python-3.x

为了找到所有作者、他们的总提交次数和电子邮件 ID,我从 GitHub 克隆了 torvalds/linux 存储库,并从 python3(版本 3.7.3)脚本中运行了以下代码:

import subprocess
p = subprocess.Popen(['git shortlog -sne HEAD'], stdout=subprocess.PIPE, shell=True)
output = p.communicate()[0]
p.wait()
print(output.decode().split('\n')) #Decoding the byte string and splitting to get a python list of result lines.
Run Code Online (Sandbox Code Playgroud)

并得到以下错误:

UnicodeDecodeError: 'utf-8' codec can't decode byte 0xb3 in position 173310: invalid start byte
Run Code Online (Sandbox Code Playgroud)

我不知道这是什么以及如何解决这个问题?

jsb*_*eno 5

问题是 Linux 提交历史记录可能(当然,考虑到结果)包含您检索的字段中未使用 utf-8 编码的数据。

\n

最简单的做法是告诉 Python 忽略错误,并在调用中用替换字符替换可能损坏的 utf-8 序列decode

\n
print(output.decode(encoding="utf-8", errors="replace").split('\\n'))\n
Run Code Online (Sandbox Code Playgroud)\n

这样做的主要问题是它会丢弃原始字符并在其位置插入 Unicode 替换字符 ('\xef\xbf\xbd')。

\n

根据您正在做什么,这就足够了(如果您只想查看屏幕上的数据,这当然就足够了)。

\n

否则,如果出于历史或法律原因这样做是为了获取所有提交者名称,那么尝试猜测不是 utf-8 的特定提交的原始编码就很重要 - 这将需要,例如try/ except 语句被要尝试的编码循环包围(例如,按顺序尝试“utf-8”,然后“latin1”,依此类推。这种方法的缺点是某些编码(例如 latin1 本身)会即使编码不正确,也不会产生错误。名称最终会被破坏。如果发生这种情况的情况很少(几十或几百个情况),那么可能值得手动修复,而不是尝试获取算法来猜测每种情况的正确编码。(找到一个损坏名称的正确拼写后,所有后续出现的情况都将得到解决)。

\n