Извлечение текста из файлов MS Word в Python

для работы с файлами MS Word в python есть расширения python win32, которые можно использовать в windows. Как мне сделать то же самое в Linux? Есть ли библиотека?

Можете ли вы дать определение «работать с»? Только чтение или тоже письмо?

Mawg says reinstate Monica 09.11.2018 12:55
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
27
1
60 706
15
Перейти к ответу Данный вопрос помечен как решенный

Ответы 15

Взгляните на как работает формат документа и создать текстовый документ с использованием PHP в Linux. Первое особенно полезно. Abiword - мой рекомендуемый инструмент. Хотя есть ограничения:

However, if the document has complicated tables, text boxes, embedded spreadsheets, and so forth, then it might not work as expected. Developing good MS Word filters is a very difficult process, so please bear with us as we work on getting Word documents to open correctly. If you have a Word document which fails to load, please open a Bug and include the document so we can improve the importer.

Но не только это! Даже самый простой текст, сохраненный в формате Word 97, почти невозможно легко понять, не полагаясь на слово, которое сделает это за вас (COM). Большинство текстовых документов не являются HTML!

William Keller 24.09.2008 07:30

Abiword не предполагает, что это HTML-документ, и, учитывая, насколько обширен этот инструмент ... Я не думаю, что это было «легко» реализовать. Abiword - это инструмент, который помогает вам читать файлы MS Word ... и, поскольку автор занимается поиском текста, этого достаточно.

Swati 24.09.2008 07:42

Ах, я всегда думал, что это слово - просто еще один текстовый редактор! Чувак, это избавило бы меня от головной боли некоторое время назад.

William Keller 24.09.2008 16:11

Я не уверен, что вам повезет без использования COM. Формат .doc до смешного сложен, и его часто называют «дампом памяти» Word во время сохранения!

В Swati это HTML, что неплохо, но большинство текстовых документов не так хороши!

OpenOffice.org может быть написан на Python: глянь сюда.

Поскольку OOo может безупречно загружать большинство файлов MS Word, я бы сказал, что это ваш лучший выбор.

Не безупречно. Близко, но, по моему опыту, далеко не безупречно (OO 2.0 - 3.0).

SpliFF 26.05.2009 19:17

Так же безупречно, как MS Word N + 1 открывает файлы MS Words N, и лучше, чем MS Word N + 1, открывает файлы MS Words N-1, IMHO

Esteban Küber 29.09.2009 18:50
Ответ принят как подходящий

Вы можете сделать вызов подпроцесса антислово. Antiword - это утилита командной строки Linux для выгрузки текста из документа Word. Очень хорошо работает с простыми документами (очевидно, теряет форматирование). Он доступен через apt и, возможно, как RPM, или вы можете скомпилировать его самостоятельно.

antiword может конвертировать текстовые документы в DocBook XML, что сохранит (по крайней мере, некоторое) форматирование.

Marius Gedminas 30.09.2015 14:38

Я знаю, что это старый вопрос, но недавно я пытался найти способ извлечь текст из файлов MS Word, и лучшее решение, которое я нашел, было с wvLib:

http://wvware.sourceforge.net/

После установки библиотеки использовать ее в Python довольно просто:

import commands

exe = 'wvText ' + word_file + ' ' + output_txt_file
out = commands.getoutput(exe)
exe = 'cat ' + output_txt_file
out = commands.getoutput(exe)

И это все. По сути, мы используем функцию commands.getouput для запуска нескольких сценариев оболочки, а именно wvText (который извлекает текст из документа Word и cat для чтения вывода файла). После этого весь текст из документа Word будет в выходной переменной и готов к использованию.

Надеюсь, это поможет любому, у кого возникнут подобные проблемы в будущем.

(Примечание: я также разместил это на этот вопрос, но здесь он кажется актуальным, поэтому, пожалуйста, извините за репост.)

Это довольно уродливо и довольно взломано, но мне кажется, что он работает для базового извлечения текста. Очевидно, чтобы использовать это в программе Qt, вам нужно было бы создать для него процесс и т.д., но командная строка, которую я взломал вместе, выглядит так:

unzip -p file.docx | grep '<w:t' | sed 's/<[^<]*>//g' | grep -v '^[[:space:]]*$'

Так вот:

распаковать -p файл.docx: -p == "распаковать в стандартный вывод"

grep '<ш: т': возьмите только строки, содержащие '<w: t' (<w: t> - это XML-элемент Word 2007 для «текста», насколько я могу судить)

sed 's / <[^ <]> // g '*: удалить все внутри тегов

grep -v '^ [[: пробел:]] $ '*: удалить пустые строки

Вероятно, есть более эффективный способ сделать это, но, похоже, он работает для меня в нескольких документах, с которыми я его тестировал.

Насколько мне известно, unzip, grep и sed имеют порты для Windows и любого из Unix, поэтому он должен быть достаточно кроссплатформенным. Несмотря на то, что это немного уродливый хакер;)

Если вы намерены использовать только модули Python без вызова подпроцесса, вы можете использовать zipfile python modude.

content = ""
# Load DocX into zipfile
docx = zipfile.ZipFile('/home/whateverdocument.docx')
# Unpack zipfile
unpacked = docx.infolist()
# Find the /word/document.xml file in the package and assign it to variable
for item in unpacked:
    if item.orig_filename == 'word/document.xml':
        content = docx.read(item.orig_filename)

    else:
        pass

Однако ваша строка содержимого должна быть очищена, один из способов сделать это:

# Clean the content string from xml tags for better search
fullyclean = []
halfclean = content.split('<')
for item in halfclean:
    if '>' in item:
        bad_good = item.split('>')
        if bad_good[-1] != '':
            fullyclean.append(bad_good[-1])
        else:
            pass
    else:
        pass

# Assemble a new string with all pure content
content = " ".join(fullyclean)

Но, безусловно, есть более элегантный способ очистить строку, возможно, используя модуль re. Надеюсь это поможет.

Чтобы удалить объекты XML, такие как & nbsp; from 'text': >>> from xml.sax.saxutils import unescape >>> text = unescape (content)

Jesvin Jose 01.08.2011 12:05

Используя модуль re, очистка может быть намного проще: stripped_content = re.compile(b'<.*?>').sub(b' ', content ) # strip tags Одна вещь, которую я не мог понять в вашем коде, - это то, почему в предыдущем фрагменте вы не используете break внутри блока if?

Vikas Prasad 04.09.2015 21:13

Ответ Бенджамин довольно хороший. Я только что консолидировал ...

import zipfile, re

docx = zipfile.ZipFile('/path/to/file/mydocument.docx')
content = docx.read('word/document.xml').decode('utf-8')
cleaned = re.sub('<(.|\n)*?>','',content)
print(cleaned)

Я должен повторить, что это работает только для docx (Word 2007 или новее). Для файлов .doc лучшим выбором будет wvware. В зависимости от вашей среды его настройка может быть сложной, но она делает очень хорошую работу.

Chad 28.12.2009 06:41

Чтобы удалить объекты XML, такие как & nbsp; from 'text': >>> from xml.sax.saxutils import unescape >>> text = unescape (очищено)

Jesvin Jose 01.08.2011 12:06

content = docx.read ('word / document.xml'). decode ('utf-8') в противном случае вы получите ошибку при очистке: TypeError: невозможно использовать строковый шаблон для байтового объекта

me_astr 10.10.2017 10:38

Используйте собственный модуль Python docx. Вот как извлечь весь текст из документа:

document = docx.Document(filename)
docText = '\n\n'.join(
    paragraph.text for paragraph in document.paragraphs
)
print(docText)

См. Сайт Python DocX

Также проверьте Textract, который вытаскивает таблицы и т. д.

Анализ XML с помощью регулярных выражений вызывает cthulu. Не делай этого!

ты делаешь здесь from docx import *? если нет, то как у вас getdocumenttext и т. д.?

dbliss 08.05.2015 01:50

opendocx в модуле нет (возможно, это было в 2009 году). Документы открываются через класс Document, например import docx; document = docx.Document('Hello world.docx').

egpbos 05.08.2015 08:40

@egpbos Я обновил пример кода, чтобы использовать python-docx нового поколения.

mikemaccana 05.08.2015 13:45

Этот код привел к ошибке для меня: paragraph.text.encode ('utf-8') для абзаца в документе .paragraphs TypeError: элемент последовательности 0: ожидаемый экземпляр str, найдены байты

MyopicVisage 02.11.2015 07:10

@MyopicVisage проверьте официальный сайт - возможно, последняя версия имеет другую подпись.

mikemaccana 02.11.2015 14:46

здесь у меня есть сценарий получения файла docx с URL-адреса http для этого, как я могу сделать эту часть

Joyson 15.02.2018 09:50

я создал вопрос на stackoverflow.com/questions/48800385/…

Joyson 15.02.2018 10:01

Unoconv также может быть хорошей альтернативой: http://linux.die.net/man/1/unoconv

Просто вариант для чтения файлов 'doc' без использования COM: Мьетта. Должен работать на любой платформе.

Если у вас установлен LibreOffice, вы можете просто вызвать его из командной строки, чтобы преобразовать файл в текст, загрузите текст в Python.

Ах, Филипп! Я просто искал способ отклонить тривиальные изменения стиля, которые вы внесли в другой мой пост. Я пытался связаться с вами напрямую. Не могли бы вы более четко изложить, что вы предлагаете здесь? Этот ответ, который я дал здесь, является ответом на вопрос. Разве этого не достаточно?

markling 08.05.2015 17:55

Re. Ваши правки стиля и грамматики: я предпочел свой собственный стиль и грамматику, спасибо. Хороший редактор не навязывает свой стиль. И действительно, ни у кого из нас нет достаточно свободного времени, чтобы заниматься тривиальной проверкой орфографии и грамматики, не так ли? Я думаю, вы можете найти это немного чрезмерным.

markling 08.05.2015 18:46

Это старый вопрос? Я считаю, что такого не существует. Есть только ответы и без ответа. На этот вопрос почти нет ответа, или, если хотите, ответ наполовину. Рассмотрены все методы чтения документов * .docx (MS Word 2007 и новее) без использования COM-взаимодействия. Но методов извлечения текста из * .doc (MS Word 97-2000), использующих только Python, не хватает. Это сложно? Сделать: не совсем, понять: ну это другое дело.

Когда я не нашел готового кода, я прочитал некоторые спецификации формата и откопал некоторые предложенные алгоритмы на других языках.

Файл MS Word (* .doc) представляет собой составной файл OLE2. Чтобы не беспокоить вас множеством ненужных деталей, подумайте об этом как о файловой системе, хранящейся в файле. Фактически он использует структуру FAT, поэтому определение остается в силе. (Хм, может быть, вы сможете монтировать его в Linux ???) Таким образом, вы можете хранить в файле больше файлов, например изображений и т. д. То же самое делается в * .docx, используя вместо этого ZIP-архив. В PyPI доступны пакеты, которые могут читать файлы OLE. Как (олефил, составные файлы, ...) Я использовал пакет составных файлов, чтобы открыть файл * .doc. Однако в MS Word 97-2000 внутренние подфайлы - это не XML или HTML, а двоичные файлы. И поскольку этого недостаточно, каждый содержит информацию о другом, поэтому вы должны прочитать как минимум два из них и соответственно распутать сохраненную информацию. Чтобы полностью понять, прочтите PDF-документ, из которого я взял алгоритм.

Приведенный ниже код составлен на скорую руку и протестирован на небольшом количестве файлов. Насколько я понимаю, все работает по назначению. Иногда какая-то тарабарщина появляется в начале и почти всегда в конце текста. И между ними могут быть какие-то странные символы.

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


doc2text module:
"""
This is Python implementation of C# algorithm proposed in:
http://b2xtranslator.sourceforge.net/howtos/How_to_retrieve_text_from_a_binary_doc_file.pdf

Python implementation author is Dalen Bernaca.
Code needs refining and probably bug fixing!
As I am not a C# expert I would like some code rechecks by one.
Parts of which I am uncertain are:
    * Did the author of original algorithm used uint32 and int32 when unpacking correctly?
      I copied each occurence as in original algo.
    * Is the FIB length for MS Word 97 1472 bytes as in MS Word 2000, and would it make any difference if it is not?
    * Did I interpret each C# command correctly?
      I think I did!
"""

from compoundfiles import CompoundFileReader, CompoundFileError
from struct import unpack

__all__ = ["doc2text"]

def doc2text (path):
    text = u""
    cr = CompoundFileReader(path)
    # Load WordDocument stream:
    try:
        f = cr.open("WordDocument")
        doc = f.read()
        f.close()
    except: cr.close(); raise CompoundFileError, "The file is corrupted or it is not a Word document at all."
    # Extract file information block and piece table stream informations from it:
    fib = doc[:1472]
    fcClx  = unpack("L", fib[0x01a2l:0x01a6l])[0]
    lcbClx = unpack("L", fib[0x01a6l:0x01a6+4l])[0]
    tableFlag = unpack("L", fib[0x000al:0x000al+4l])[0] & 0x0200l == 0x0200l
    tableName = ("0Table", "1Table")[tableFlag]
    # Load piece table stream:
    try:
        f = cr.open(tableName)
        table = f.read()
        f.close()
    except: cr.close(); raise CompoundFileError, "The file is corrupt. '%s' piece table stream is missing." % tableName
    cr.close()
    # Find piece table inside a table stream:
    clx = table[fcClx:fcClx+lcbClx]
    pos = 0
    pieceTable = ""
    lcbPieceTable = 0
    while True:
        if clx[pos]= = "\x02":
            # This is piece table, we store it:
            lcbPieceTable = unpack("l", clx[pos+1:pos+5])[0]
            pieceTable = clx[pos+5:pos+5+lcbPieceTable]
            break
        elif clx[pos]= = "\x01":
            # This is beggining of some other substructure, we skip it:
            pos = pos+1+1+ord(clx[pos+1])
        else: break
    if not pieceTable: raise CompoundFileError, "The file is corrupt. Cannot locate a piece table."
    # Read info from pieceTable, about each piece and extract it from WordDocument stream:
    pieceCount = (lcbPieceTable-4)/12
    for x in xrange(pieceCount):
        cpStart = unpack("l", pieceTable[x*4:x*4+4])[0]
        cpEnd   = unpack("l", pieceTable[(x+1)*4:(x+1)*4+4])[0]
        ofsetDescriptor = ((pieceCount+1)*4)+(x*8)
        pieceDescriptor = pieceTable[ofsetDescriptor:ofsetDescriptor+8]
        fcValue = unpack("L", pieceDescriptor[2:6])[0]
        isANSII = (fcValue & 0x40000000) == 0x40000000
        fc      = fcValue & 0xbfffffff
        cb = cpEnd-cpStart
        enc = ("utf-16", "cp1252")[isANSII]
        cb = (cb*2, cb)[isANSII]
        text += doc[fc:fc+cb].decode(enc, "ignore")
    return "\n".join(text.splitlines())

Для чтения файлов Word 2007 и более поздних версий, включая файлы .docx, можно использовать пакет python-docx:

from docx import Document
document = Document('existing-document-file.docx')
document.save('new-file-name.docx')

Чтобы читать файлы .doc из Word 2003 и более ранних версий, вызовите подпроцесс антислово. Сначала вам нужно установить антислово:

sudo apt-get install antiword

Затем просто вызовите его из своего скрипта python:

import os
input_word_file = "input_file.doc"
output_text_file = "output_file.txt"
os.system('antiword %s > %s' % (input_word_file, output_text_file))

Aspose.Words Cloud SDK для Python - независимое от платформы решение для преобразования файлов MS Word / Open Office в текст. Это коммерческий продукт, но бесплатный пробный план предусматривает 150 ежемесячных вызовов API.

P.S: Я евангелист-разработчик в Aspose.

# For complete examples and data files, please go to https://github.com/aspose-words-cloud/aspose-words-cloud-python
# Import module
import asposewordscloud
import asposewordscloud.models.requests
from shutil import copyfile

# Please get your Client ID and Secret from https://dashboard.aspose.cloud.
client_id='xxxxxxx-xxxx-xxxx-xxxxx-xxxxxxxxxx'
client_secret='xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'

words_api = asposewordscloud.WordsApi(client_id,client_secret)
words_api.api_client.configuration.host='https://api.aspose.cloud'

filename = 'C:/Temp/02_pages.docx'
dest_name = 'C:/Temp/02_pages.txt'
#Convert RTF to text
request = asposewordscloud.models.requests.ConvertDocumentRequest(document=open(filename, 'rb'), format='txt')
result = words_api.convert_document(request)
copyfile(result, dest_name)

Другие вопросы по теме