texto extraindo palavra MS arquivos em python
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?
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
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 '
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.