Код utf-8 c не может декодировать байт - Python - PullRequest
2 голосов
/ 05 апреля 2020
Приложение

My Django работает с типами файлов .txt и .doc. И это приложение открывает файл, сравнивает его с другими файлами в БД и распечатывает некоторый отчет.

Теперь проблема в том, что, когда тип файла .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)

1 Ответ

1 голос
/ 06 апреля 2020

Не существует общего кодирования, которое автоматически знает, как декодировать уже кодированный файл в заданной кодировке c.

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 open(str(last_uploaded.document), encoding="utf-8", errors="ignore") as fr:
    original_words = fr.read().lower().split()
    ...

(Примечание: вам не нужно использовать библиотеку codecs, если вы используете Python 3, но вы пометили свой вопрос с помощью python-2.7.)

Вы можете увидеть Преимущества и недостатки использования различных обработчиков ошибок здесь и здесь . Вы должны знать, что если не использовать обработчик ошибок, по умолчанию будет использоваться errors="strict", который вы, вероятно, не хотите. Другие параметры могут быть почти самоочевидными, например:

  • с использованием errors="replace" заменит некодируемый символ подходящим маркером замены
  • с использованием errors="ignore" просто проигнорирует символ и продолжает чтение данных файла.

То, что вы должны использовать, зависит от ваших потребностей и вариантов использования.

Вы говорите, что у вас также есть проблемы с кодированием не только с простым текстом файлы, но также с проприетарными doc файлами:

Формат .doc - это не простой текстовый файл, который можно просто прочитать с помощью open() или codecs.open(), поскольку в двоичном формате хранится много информации см. этот сайт для получения дополнительной информации. Таким образом, вам нужен специальный читатель для .doc файлов, чтобы получить текст из него. Какая библиотека вы используете, зависит от вашей версии Python и, возможно, также от операционной системы, которую вы используете. Может быть, это хорошая отправная точка для вас.

К сожалению, использование библиотеки не полностью предотвращает ошибки кодирования. (Может быть, да, но я не уверен, что кодировка сохраняется в самом файле , как в .docx файле .) Возможно, у вас также есть изменение на , чтобы выяснить кодировку файл . Способ обработки ошибок кодирования, вероятно, зависит от самой библиотеки.

Так что я просто предполагаю, что вы пытаетесь открыть файлы .doc в виде простых текстовых файлов. Тогда вы получите ошибки декодирования, потому что они не сохраняются как текст, читаемый человеком. И даже если вы избавитесь от ошибки, вы увидите только текст, не читаемый человеком: (Я создал простой текстовый файл с LibreOffice в формате doc (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' ...
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...