首页 > 解决方案 > “utf-8”编解码器无法解码字节 - Python

问题描述

我的 Django 应用程序同时使用.txt.doc文件类型。这个应用程序打开一个文件,将它与 db 中的其他文件进行比较并打印出一些报告。

现在的问题是,当文件类型为 时.txt,我收到'utf-8' codec can't decode byte错误(这里我使用的是encoding='utf-8')。当我切换encoding='utf-8'encoding='ISO-8859-1'错误更改为'latin-1' codec can't decode byte.

我想找到适用于每种类型文件的这种编码格式。这是我的功能的一小部分:

views.py

@login_required(login_url='sign_in')
def result(request):
    last_uploaded = OriginalDocument.objects.latest('id')
    original = open(str(last_uploaded.document), 'r', encoding='utf-8')
    original_words = original.read().lower().split()
    words_count = len(original_words)
    open_original = open(str(last_uploaded.document), "r")
    read_original = open_original.read()
    report_fives = open("static/report_documents/" + str(last_uploaded.student_name) + 
    "-" + str(last_uploaded.document_title) + "-5.txt", 'w')
    # Path to the documents with which original doc is comparing
    path = 'static/other_documents/doc*.txt'
    files = glob.glob(path)

    rows, found_count, fives_count, rounded_percentage_five, percentage_for_chart_five, fives_for_report, founded_docs_for_report = search_by_five(last_uploaded, 5, original_words, report_fives, files)

    context = {
      ...
    }

    return render(request, 'result.html', context)

标签: pythondjangopython-2.7django-viewsdjango-templates

解决方案


没有通用编码可以自动知道如何以特定编码解码已编码的文件。

UTF-8 是一个不错的选择,它与其他编码具有许多兼容性。例如,您可以像这样简单地ignore或无法解码的字符:replace

from codecs import open
original = open(str(last_uploaded.document), encoding="utf-8", errors="ignore")
original_words = original.read().lower().split()
...
original.close()

甚至使用为您关闭文件的上下文管理器(with 语句):

with open(str(last_uploaded.document), encoding="utf-8", errors="ignore") as fr:
    original_words = fr.read().lower().split()
    ...

(注意:如果您使用的是 Python 3,则不需要使用该codecs库,但您已用 标记了您的问题python-2.7。)

您可以在此处此处查看使用不同错误处理程序的优点和缺点。您必须知道不使用错误处理程序将默认使用errors="strict"您可能不想要的。其他选项可能几乎不言自明,例如:

  • usingerrors="replace"将用合适的替换标记替换不可解码的字符
  • usingerrors="ignore"将简单地忽略该字符并继续读取文件数据。

您应该使用什么取决于您的需求和用例。

你是说你不仅有纯文本文件的编码问题,还有专有doc文件的编码问题:

.doc格式不是纯文本文件,您可以简单地阅读它,open()或者codecs.open()因为有许多信息以二进制格式存储,请参阅此站点以获取更多信息。因此,您需要一个特殊的.doc文件阅读器才能从中获取文本。您使用的库取决于您的 Python 版本,也可能取决于您使用的操作系统。也许这对您来说是一个很好的起点

不幸的是,使用库并不能完全避免编码错误。(也许是的,但我不确定编码是否像文件一样保存在.docx文件本身中。)您也许还有机会弄清楚文件的编码。如何处理编码错误可能取决于库本身。

所以我只是猜测您正在尝试将.doc文件作为简单的文本文件打开。然后你会得到解码错误,因为它没有保存为人类可读的文本。即使您摆脱了错误,您也只会看到非人类可读的文本:(我使用 LibreOffice 创建了一个简单的文本文件,格式为doc-format(Microsoft Word 1997-2003)):

In [1]: open("./test.doc", "r").read()
UnicodeDecodeError: 'utf-8' codec can`t decode byte 0xd0 in position 0: invalid continuation byte

In [2]: open("./test.doc", "r", errors="replace").read()  # or open("./test.doc", "rb").read()
'��\x11\u0871\x1a�\x00\x00\x00' ...

推荐阅读