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

3

我正在从目录中获取数据,它以字节格式提供数据。

字节数据:

b'\x80\x00\x00\x00\n\x00\x00%\x83\xa0\x08\x01\x00\xbb@\x00\x00\x05p 
\x02\x00>\xf3\x00\x00\x00}\x02\x00`\x03\xef0\x00\x00\r\xc0 
\x06\xf0>\xf3\x00\x00\x02\x88\x02\x03\xec\x03\xef0\x00\x00/.....'

将这些数据转换为字符串或任何可读格式时,我遇到了以下错误:
UnicodeDecodeError: 'utf-8' codec can't decode byte 0x80 in position 0: invalid start byte

我使用的代码(Python 3.7.3):

blobs = blob.decode('utf-8')

并且

import json
json.dumps(blob.decode())

我还尝试了 pickleastpprint,但它们在这里并没有帮助。

我尝试的方法:


2
这不是可读数据,因此您无法将其解码为utf-8。 - tkausl
@tkausl 那么有没有办法使它可读? - L Lawliet
@tkausl 这可能是可读数据,但绝对不是 UTF-8。 - Wolf
“有没有办法让这个更易读?” - 在我看来,您在问题中展示的是最好的使其易读的方式。 - Wolf
你说“来自目录” - 请添加你正在/曾经使用的哪个目录。 - Wolf
4个回答

4

UTF-8编码 具有一些内置的冗余,起到至少两个目的:

1) 正反向读取代码点位置

起始字节(在二进制点中携带实际数据)匹配以下4种模式之一

0.......
110.....
1110....
11110...

而续字节(0至3)始终具有此形式。
10......

2) 检查有效性

如果不遵守此编码规则,可以肯定这不是UTF-8数据,例如在传输过程中发生了损坏。

结论

为什么可以说b'\x80\'不是UTF-8? 在前两个字节就已经违反了编码规则:因为80必须是一个连续字节。这正是您的错误信息所说的:

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

即使您跳过这个问题,在b'%\x83'几个字节之后还会出现另一个问题,所以很可能您正在尝试解码错误的数据或者假设错误的编码方式。


1
如果您投了反对票,请解释一下这个答案有什么问题。谢谢! - Wolf
1
不是我投的反对票,但仅仅证明UTF-8不是这些数据的正确编码方式只能算是一个半吊子的回答。在我看来,显然这个输入根本不是文本,所以讨论某种特定的文本编码方式完全离题。 - tripleee
@tripleee 感谢您的提示。我可能对UTF-8有点过于着迷了。我的想法是展示我们可以确信错误消息的正确性。 - Wolf

3

你可以尝试忽略无法读取的块。

blobs.decode('utf-8', 'ignore')

这不是一个很好的解决方案,但是生成字节对象的方式存在一些问题。也许,utf-8不是你数据的适当编码方式。


你的字节中有 \,这对于 Python 中的字符串是一个问题。这些可能需要用 \\ 替换。 - user13295467
这是在很多层面上都是错误的。从主要不是ASCII字符集的数据中有效地提取只有ASCII字节几乎永远不会有用。 - tripleee

2
您的示例数据显然不是任何常见编码的文本。Python和我们都无法将明显不是文本的数据转换为字符串。
如果这是一个明确定义的二进制文件格式,请找到该格式的解析器(最好是流行的Python库,但对于更晦涩或专有的格式,您可能无法找到解析器),或者如果您可以弄清楚数据的结构,可以自己编写解析器,通过聪明的实验和猜测,或者找到(即使不是权威的,也可能是第三方的)文档来帮助您。
如果您只想将字节转换为具有相同Unicode代码点的代码点字符串(例如,输入字节\xff映射到Unicode代码点U+00FF),则使用'latin-1'编码可以实现这一点,虽然有些晦涩但非常方便。在这种情况下,结果显然不是有用的人类可读文本;在许多方面,将数据保留为字节可能更自然,很可能会更少出错,并且更方便。

也许十六进制转储也有帮助。但我认为关键是使用了哪个目录。 - Wolf

0

针对这个编码错误

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

或者类似的操作,您只需要使用扩展名为.json的数据库文件,并将编码更改为UTF-8(例如在VScode中,您可以在右下角导航栏中更改),然后保存文件...

现在运行

 $ git status

你会得到类似于这样的结果

 On branch master
 Changes not staged for commit:
   (use "git add <file>..." to update what will be committed)
   (use "git restore <file>..." to discard changes in working directory)
        modified:   store/dumps/store.json
   (use "git add <file>..." to include in what will be committed)
        .gitignore

 no changes added to commit (use "git add" and/or "git commit -a")

或者类似这样的一个
On branch master
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        modified:   store/dumps/store.json
Untracked files:
  (use "git add <file>..." to include in what will be committed)
        .gitignore

对于第一个情况,你只需要这样做

$ git add store/dumps/

第二种情况不需要这个前面的部分...

现在,对于这两种情况,您需要使用以下命令提交更改:

$ git commit -m "launching to production"

控制台会返回一条消息,告诉您有关添加和更改的信息...

您需要再次为应用程序构建日志

$ git push heroku master

(针对Heroku用户)
构建完成后,您只需再次加载数据库即可。
heroku run python manage.py loaddata store/dumps/store.json

它将安装这些对象。

对不起,我的英语水平不好!!!


这似乎有些误导。按定义,JSON文件应该已经包含UTF-8。我猜你假设文件包含不同的编码方式,并且很可能OP是Windows用户。 - tripleee

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接