Ошибка обработки файлов RTF на python

Всем добрый день! Сломал всю голову с таким вопросом: Написал код:

import pyperclip
import os
from striprtf.striprtf import rtf_to_text

rtf = open('01-08.2020.rtf').read()
text = rtf_to_text(rtf)
a = text.encode('iso-8859-1').decode('cp1251')
i = a.find('Поступ.')
if i != -1:
    a = a[:i]
pyperclip.copy(a)

и все работает как часы, если вначале rtf файла не стоит скрытый текст в виде "разрыва раздела" после чего программа пишет ошибку:

UnicodeEncodeError: 'latin-1' codec can't encode characters in position 34-35: ordinal not in range(256)

программа явно ругается на строку, так как iso-8859-1 не может декодировать скрытый текст написанный в RTF-ке:

a = text.encode('iso-8859-1').decode('cp1251')

Так как я в питоне человек новый и понятия не имею как предварительно проверить текст на скрытые символы решил пойти другим путем, а именно: удалить строку на которую ругается компилятор, в итоге получился код:

import pyperclip
    import os
    from striprtf.striprtf import rtf_to_text
    text = rtf_to_text(rtf)
    a = text.encode('iso-8859-1').decode('cp1251')
    i = a.find('Поступ.')
    if i != -1:
        a = a[:i]
    pyperclip.copy(a)

Но в нем некорректно кодируется часть слов как пример:

ВЫПИСКА ÈÇ ËÈÖÅÂÎÃÎ Ñ×ÅÒÀ а должна быть ВЫПИСКА ИЗ ЛИЦЕВОГО СЧЕТА В сухом остатке я вижу два пути либо как то проверять файл на скрытый текст перед декодированием, либо работать с "кривым" текстом и заменять некорректные буквы правильными... Уважаемые профессионалы, если сможете помочь советом буду благодарен спасибо!!!


Ответы (1 шт):

Автор решения: gil9red

Покопался в исходниках striprtf, нашел место, где кириллица превращается в кракозябры:

c = int(hex, 16)
if c > 127:
    out.append(chr(c))  # NOQA
else:
    out.append(chr(c))

Я ее заменил на (в encoding передавал cp1251):

c = int(hex, 16)
out.append(
    bytes([c]).decode(encoding)
)

И сделал пример с небольшой доработкой (в my_rtf_to_text находится копия исходника striprtf с той доработкой, файл с текстом есть в примере):

from my_rtf_to_text import rtf_to_text

# NOTE: file header: {\rtf1\adeflang1025\ansi\ansicpg1251\
rtf = open('EULA_RUS.rtf', encoding='ansi').read()

print(
    rtf_to_text(rtf, encoding='cp1251')
)
# MICROSOFT SOFTWARE LICENSE TERMS
# MICROSOFT SQL SERVER COMPACT 4.0 SERVICE PACK 1 (SP1)
# Настоящие условия лицензии являются соглашением между корпорацией Microsoft (или, в зависимости от места вашего проживания, одним из ее аффилированных лиц) и вами. Прочтите их внимательно. Они применяются к вышеуказанному программному обеспечению, включая носители, на которых оно распространяется (если они есть). Эти условия распространяются также на все
# обновления,
# дополнительные компоненты,
# службы Интернета,
# службы технической поддержки
# Microsoft для данного программного обеспечения, если эти элементы не сопровождаются другими условиями. В последнем случае применяются соответствующие условия.

PS.

Пока искал информацию по rtf to text, узнал как определять кодировку с которой работать.

В начале файла rtf она указывается, например {\rtf1\adeflang1025\ansi\ansicpg1251\ говорит что:

  • сам файл закодирован ansi (по-моему, это кодировка по умолчанию)
  • ansicpg1251 -- текст кодируется в cp1251 (windows-1251)
→ Ссылка