4

Столкнулся с проблемой на python3 - прочитать из файла текст на кириллице (rtf, txt фаил). Выводит в терминал непонятные значения типа u/2424 и тд. Перепробовал все, не могу понять как перекодировать его чтобы выводил нормально. И как прочитать из файла одно слово? Спасибо за ответ! Так же открывал таким методом. Вывод не меняется!

open('...', 'r', encoding='utf-8')

file = open('some_text.rtf', 'r')
print(file.readlines())

Вот такой вывод кирилицы:

['\xd0\x92\xd0\xb0\xd1\x88 \xd1\x88\xd0\xb5\xd0\xb4\xd0\xb5\xd0\xb2\xd1\x80 \xd0\xb3\xd0\xbe\xd1\x82\xd0\xbe\xd0\xb2!\n', '\xd0\xa1 \xd0\xb4\xd1\x80\xd1\x83\xd0\xb3\xd0\xbe\xd0\xb9
insolor
  • 49,104
  • Покажите свой код и напишите, что он выводит фактически. – insolor Jun 02 '16 at 06:20
  • В open есть параметр encoding, если его не указывать, кодировка берется системная. Укажите в нем кодировку файла. Например: open('...', 'r', encoding='utf-8') – gil9red Jun 02 '16 at 06:38
  • делал не помогает, вывод не меняеться

    также писал в начале файла #encoding utf-8 тоже не помогло

    – Вадим Вова Jun 02 '16 at 06:39
  • @ВадимВова, добавьте в вопрос, с какой кодировкой открываете, и что выводится. Иначе это будет гадание на кофейной гуще. – insolor Jun 02 '16 at 06:40
  • Кстати, RTF - это не plain-text формат. Почитайте, например здесь: Хабрахабр: Текст любой ценой: RTF – insolor Jun 02 '16 at 06:42
  • Выводит набор цифры типа u/2424 Та же ситуация и с .txt Возможно на маке другая кодировка? – Вадим Вова Jun 02 '16 at 06:44
  • @ВадимВова, еще раз. Выше вы пишете, что пробовали открывать с encoding. С какой кодировкой пробуете открывать? По поводу вывода - скопируйте и вставьте буквально то что выводит программа. Также посмотрите что на самом деле находится в файле (откройте файл с помощью блокнота, например). – insolor Jun 02 '16 at 06:48
  • То что вы привели в качестве вывода не соответствует по виду тому, что вы писали раньше. Видимо раньше вы открывали rtf, а теперь показываете вывод при открытии файла txt. Для открытия файла txt вам в данном случае скорее всего нужно указать кодировку cp1251. – insolor Jun 03 '16 at 05:19
  • @insolor спасибо, что опечатку поправили. Вывод показывает, что OP использует Питон 2, а не 3. То есть текстовый файл читается как байты (в UTF-8 кодировке в данном случае) и есть вероятность что кракозябы при печати появятся в не UTF-8 окружении. – jfs Jun 03 '16 at 10:24
  • @jfs, может и так. Я сейчас попробовал записать эти данные в файл, потом прочитать с кодировкой utf-8 в Python3 - получилось ['Ваш шедевр готов!\n', 'С другой']. Если бы в вопросе была описана внятная последовательность действий, и не два вопроса в одном, то можно было бы что-то посоветовать. А так можно только гадать. – insolor Jun 03 '16 at 10:35

2 Answers2

3

RTF - не plain-text файл и просто так из него ничего прочитать не выйдет. В нем дополнительно хранятся таблицы шрифтов, цветов, стилей и еще неведомо чего. Более того, судя по всему текст там хранится не в виде байтов u/1234, а в виде строк 'u/1234' (!) (или для другой подходящей кодировки, например, win-1251 - в этом случае кирилица представлена строками типа \'b2, \'a4). Благо, есть парочка старых библиотек. Вот пример для pyth (для простого файла с одной строкой сработало):

from pyth.plugins.rtf15.reader import Rtf15Reader

doc = Rtf15Reader.read(open("doc.rtf", "r"))

for paragraph in doc.content:
    for word in paragraph.content:
        print(word.__dict__["content"])  # Вывод в виде unicode строки

С документацией плоховато и неизвестно как именно библиотека справляется с таблицами, изображениями.

m9_psy
  • 6,449
  • Также открывать и текстовый файл (txt) есть ли разница при работе на маке или винде( имею ввиду, кодировку) – Вадим Вова Jun 02 '16 at 08:45
  • работает ли эта библиотека на Питоне 3? – jfs Jun 02 '16 at 09:19
  • @ВадимВова, если в open указывать правильную кодировку открываемого файла txt, то будет правильно открывать файлы и на маке, и на винде, и на линуксе. – insolor Jun 02 '16 at 12:25
  • @ВадимВова, если есть вопросы по txt - создвайте отдельный вопрос. – m9_psy Jun 02 '16 at 14:26
  • Похоже pyth работает только на Питоне 2 и не понимает \ucN команду и суррогатные пары (нужны для не BMP символов) – jfs Jun 03 '16 at 10:30
1

Если на машине уже стоит LibreOffice, то можно на него опереться, чтобы поддерживать даже астральные символы такие как смайлики, флаги итд. pyth и большинство других rtf-библиотек могут потерять символы из rtf-документа с символами, требующих utf-16 суррогатных пар, пример test.rtf:

{\rtf1\ansi\ansicpg1251\uc0 test [\'ff] [\u9786] [\u-10187\u-9138]
 [\u-10180\u-8710\u-10180\u-8712].}

Команда $ rtf2txt test.rtf сохраняет текст в test.txt и печатает его:

test [я] [☺] [] [].

где rtf2txt:

#!/usr/bin/env python3
"""Convert rtf-file(s) to plain text using LibreOffice.

  Usage: rtf2txt <rtf-file>...
"""
from getpass import getuser
from pathlib import Path
from subprocess import DEVNULL, check_call
from sys import argv
from tempfile import TemporaryDirectory

filenames = argv[1:]
with TemporaryDirectory('LibreOffice_Conversion_' + getuser()) as td:
    check_call([
        'soffice',
        '--headless',  # implied by convert-to
        # https://wiki.openoffice.org/wiki/Documentation/DevGuide/Spreadsheets/Filter_Options
        '--infilter="Rich Text Format (StarCalc)"',  # limit input formats
        # specify the encoding explicitly for the output
        '--convert-to', 'txt:Text (encoded):UTF8',
        # https://bugs.documentfoundation.org/show_bug.cgi?id=37531
        '-env:UserInstallation=' + Path(td).as_uri()
    ] + filenames, stdout=DEVNULL)

for path in map(Path, filenames):
    print(path.with_suffix('.txt').read_text('utf-8'))
jfs
  • 52,361