Pergunta

para trabalhar com arquivos do Word MS em python, há extensões win32 Python, que pode ser usado no Windows. Como posso fazer o mesmo em linux? Existe alguma biblioteca?

Foi útil?

Solução

Você poderia fazer uma chamada subprocesso para antiword . Antiword é um utilitário de linha de comando linux para despejar texto fora de uma palavra doc. Funciona muito bem para documentos simples (obviamente ele perde formatação). Ele está disponível através apt, e provavelmente como RPM, ou você pode compilá-lo.

Outras dicas

Use o Python nativa docx módulo . Veja como extrair todo o texto de um documento:

document = docx.Document(filename)
docText = '\n\n'.join([
    paragraph.text.encode('utf-8') for paragraph in document.paragraphs
])
print docText

Python DocX

Também confira Textract que puxa para fora tabelas etc.

XML Parsing com regexs Invoca cthulu. Não fazê-lo!

resposta benjamin 's é um muito bom. Acabo consolidou ...

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)

OpenOffice.org pode ser programado com Python:. ver aqui

Desde OOo pode carregar a maioria dos arquivos MS Word na perfeição, eu diria que é a sua melhor aposta.

Eu sei que isto é uma questão antiga, mas eu estava recentemente tentando encontrar uma maneira de extrair texto de arquivos do Word MS, e a melhor solução, de longe, eu encontrei foi com wvLib:

http://wvware.sourceforge.net/

Depois de instalar a biblioteca, usá-lo em Python é muito fácil:

import commands

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

E é isso. Praticamente, o que estamos fazendo é usando a função commands.getouput para executar um par de scripts shell, ou seja, wvText (que extrai o texto de um documento do Word, e gato para ler a saída do arquivo). Depois disso, todo o texto do documento do Word será na variável para fora, pronto para uso.

Esperamos que este vai ajudar alguém com problemas semelhantes no futuro.

Dê uma olhada formato doc como o formato doc obras e criar documento do Word usando PHP no Linux . O primeiro é especialmente útil. Abiword é minha ferramenta recomendada. Há limitações entanto:

No entanto, se o documento tiver tabelas complicadas, caixas de texto, folhas de cálculo incorporados, e assim por diante, então ele pode não funcionar como esperado. Desenvolver bons filtros de MS Word é um processo muito difícil, por isso, tenha-se a nós trabalhar em obter documentos do Word para abrir corretamente. Se você tiver um documento do Word que deixa de carga, por favor, abra um erro e incluir o documento para que possamos melhorar o importador.

(Nota: eu postei isso na esta questão bem, mas parece relevante aqui, por isso, desculpa o repost.)

Agora, isso é muito feio e muito hacky, mas parece trabalhar para mim para extração de texto básico. Obviamente, para usar isso em um programa Qt você teria que gerar um processo para ele etc, mas a linha de comando Eu tenho cortado em conjunto é:

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

Então, isso é:

unzip -p file.docx : p == "unzip para stdout"

grep ': Pegue apenas as linhas que contêm ' é o elemento XML do Word 2007 para "texto", tanto quanto eu posso dizer)

sed 's / <[^ <] > // g' *: remover tudo dentro de tags

grep -v '^ [[: space:]] $' *: linhas Remove em branco

Não é provável uma maneira mais eficiente de fazer isso, mas parece trabalhar para mim nas poucas docs eu testei com ele.

Tanto quanto eu estou ciente, unzip, grep e sed todos têm portas para o Windows e qualquer um dos Unixes, por isso deve ser razoavelmente cross-platform. Despit ser um pouco de um corte feio;)

Se a sua intenção é usar puramente python módulos sem chamar um subprocesso, você pode usar o arquivo zip 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

A sua cadeia de conteúdo no entanto precisa de ser limpo, uma maneira de fazer isso é:

# 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)

Mas há certamente uma maneira mais elegante para limpar a corda, provavelmente usando o módulo re. Espero que isso ajude.

Unoconv também pode ser uma boa alternativa: http://linux.die.net/man/ 1 / unoconv

Se você tem LibreOffice instalado, você pode simplesmente chamá-lo a partir da linha de comando para converter o arquivo para texto, em seguida, carregar o texto em Python.

Eu não tenho certeza se você vai ter muita sorte sem usar COM. O formato .doc é ridiculamente complexa, e é muitas vezes chamado de "despejo de memória" da Palavra no momento de salvar!

No Swati, que está em HTML, que é fino e elegante, mas a maioria dos documentos de texto não são tão bom!

Para ler Word 2007 e arquivos posteriores, incluindo arquivos .docx, você pode usar o python-docx pacote :

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

Para ler arquivos .doc do Word 2003 e versões anteriores, fazer uma chamada subprocesso para antiword . Você precisa instalar antiword primeiro:

sudo apt-get install antiword

Em seguida, basta chamá-lo de seu script 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))

Esta é uma questão de idade? Eu acredito que tal coisa não existe. Não só são respondidas e as não respondidas. Este é bastante sem resposta, ou metade respondeu, se desejar. Bem, métodos para a leitura * .docx (MS Word 2007 e posterior) documentos sem usar interoperabilidade são todos cobertos. Mas os métodos para extrair texto de * .doc (MS Word 97-2000), usando apenas Python, não tem. É este complicado? Para fazer: não realmente, compreender:. Bem, isso é outra coisa

Quando eu não encontrou qualquer código acabado, eu li algumas especificações de formatos e cavou alguns algoritmos propostos em outros idiomas.

arquivo de MS Word (* .doc) é um arquivo composto OLE2. Não incomodá-lo com um monte de detalhes desnecessários, pense nisso como um sistema de arquivo armazenado em um arquivo. Ele realmente usa a estrutura FAT, então a definição detém. (Hm, talvez você possa ciclo montar-lo no Linux ???) Desta forma, você pode armazenar mais arquivos dentro de um arquivo, como fotos etc. O mesmo é feito em * .docx usando arquivo ZIP em seu lugar. Existem pacotes disponíveis no PyPI que podem ler arquivos OLE. Curtir (olefile, compoundfiles, ...) Eu costumava pacote compoundfiles abrir o arquivo .doc *. No entanto, em MS Word 97-2000, subfiles internos não são XML ou HTML, mas arquivos binários. E como isso não é suficiente, cada um contém uma informação sobre outro, então você tem que ler pelo menos dois deles e desvendar armazenadas informações em conformidade. Para entender completamente, leia o documento PDF a partir do qual eu levei o algoritmo.

código abaixo é muito apressadamente composta e testado em pequeno número de arquivos. Tanto quanto eu posso ver, ele funciona como pretendido. Às vezes, alguns rabiscos aparece no início, e quase sempre no final do texto. E não pode haver alguns caracteres estranhos in-between também.

Aqueles que apenas deseja procurar texto será feliz. Ainda assim, exorto qualquer pessoa que pode ajudar a melhorar este código para fazê-lo.


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())

Apenas uma opção para a leitura 'doc' arquivos sem usar COM: miette . Deve funcionar em qualquer plataforma.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top