Domanda

per lavorare con i file MS Word in Python, esistono estensioni Python Win32, che possono essere utilizzate in Windows. Come faccio a fare lo stesso in Linux? C'è qualche biblioteca?

È stato utile?

Soluzione

È possibile effettuare una chiamata di sottoprocesso a antiword . Antiword è un'utilità della riga di comando di Linux per scaricare il testo da una parola doc. Funziona abbastanza bene per documenti semplici (ovviamente perde la formattazione). È disponibile tramite apt, e probabilmente come RPM, oppure potresti compilarlo tu stesso.

Altri suggerimenti

Utilizza il modulo docx nativo di Python . Ecco come estrarre tutto il testo da un documento:

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

Vedi sito Python DocX

Dai un'occhiata anche a Textract che estrae le tabelle ecc.

L'analisi di XML con regexs richiama cthulu. Non farlo!

benjamin la risposta è piuttosto buona. Ho appena consolidato ...

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 può essere scritto con Python: vedi qui .

Dato che OOo può caricare la maggior parte dei file MS Word in modo impeccabile, direi che è la soluzione migliore.

So che questa è una vecchia domanda, ma di recente stavo cercando di trovare un modo per estrarre il testo dai file MS Word e la soluzione migliore di gran lunga che ho trovato era con wvLib:

http://wvware.sourceforge.net/

Dopo aver installato la libreria, usarla in Python è abbastanza semplice:

import commands

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

E questo è tutto. Praticamente, quello che stiamo facendo è usare la funzione command.getouput per eseguire un paio di script di shell, vale a dire wvText (che estrae il testo da un documento Word e cat per leggere l'output del file). Successivamente, l'intero testo del documento Word sarà nella variabile out, pronto per l'uso.

Speriamo che questo possa aiutare chiunque abbia problemi simili in futuro.

Dai un'occhiata a come funziona il formato doc funziona e creare documento word usando PHP in linux . Il primo è particolarmente utile. Abiword è il mio strumento raccomandato. Ci sono limitazioni sebbene:

  

Tuttavia, se il documento ha tabelle complicate, caselle di testo, fogli di calcolo incorporati e così via, potrebbe non funzionare come previsto. Lo sviluppo di buoni filtri di MS Word è un processo molto difficile, quindi ti preghiamo di tener fede a noi mentre lavoriamo per aprire correttamente i documenti di Word. Se hai un documento Word che non si carica, ti preghiamo di aprire un bug e includere il documento in modo da poter migliorare l'importatore.

(Nota: l'ho pubblicato su questa domanda , ma qui sembra pertinente, quindi scusate il ripubblicare.)

Ora, questo è piuttosto brutto e piuttosto confuso, ma sembra funzionare per me per l'estrazione di base del testo. Ovviamente per usarlo in un programma Qt dovresti generare un processo per esso ecc., Ma la riga di comando che ho hackerato insieme è:

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

Quindi questo è:

decomprimere -p file.docx : -p == " decomprimere in stdout "

grep '< w: t' : prendi solo le righe che contengono '< w: t' (< w: t > ; è l'elemento XML di Word 2007 per " text " ;, per quanto ne so)

sed 's / < [^ <] > // g' *: rimuove tutto all'interno dei tag

grep -v '^ [[:: space]] $' *: rimuove le righe vuote

C'è probabilmente un modo più efficiente per farlo, ma sembra funzionare per me sui pochi documenti con cui l'ho provato.

Per quanto ne so, decomprimere, grep e sed hanno tutte le porte per Windows e uno qualsiasi degli Unix, quindi dovrebbe essere ragionevolmente multipiattaforma. Despit è un po 'un brutto hack;)

Se la tua intenzione è quella di utilizzare moduli puramente python senza chiamare un sottoprocesso, puoi usare il modus python zipfile.

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

La tua stringa di contenuti deve comunque essere ripulita, un modo per farlo è:

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

Ma c'è sicuramente un modo più elegante per ripulire la stringa, probabilmente usando il modulo re. Spero che questo aiuti.

Unoconv potrebbe anche essere una buona alternativa: http://linux.die.net/man/ 1 / unoconv

Se hai installato LibreOffice, puoi semplicemente chiamarlo dalla riga di comando per convertire il file in testo , quindi caricare il testo in Python.

Non sono sicuro che avrai molta fortuna senza usare COM. Il formato .doc è ridicolmente complesso ed è spesso chiamato & Quot; dump della memoria & Quot; di Word al momento del salvataggio!

In Swati, questo è in HTML, che è bello e dandy, ma molti documenti di parole non sono così belli!

Per leggere i file Word 2007 e successivi, inclusi i file .docx, è possibile utilizzare python-docx pacchetto:

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

Per leggere i file .doc da Word 2003 e precedenti, effettuare una chiamata di sottoprocesso a antiword . Devi prima installare antiword:

sudo apt-get install antiword

Quindi chiamalo dal tuo 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))

È una vecchia domanda? Credo che tale cosa non esista. Ci sono solo quelli con risposta e senza risposta. Questo è piuttosto senza risposta, o metà risposta se lo desideri. Bene, i metodi per leggere documenti * .docx (MS Word 2007 e successivi) senza usare l'interoperabilità COM sono tutti coperti. Ma mancano i metodi per estrarre il testo da * .doc (MS Word 97-2000), usando solo Python. È complicato? Fare: non proprio, per capire: bene, questa è un'altra cosa.

Quando non ho trovato alcun codice finito, ho letto alcune specifiche del formato e ho estratto alcuni algoritmi proposti in altre lingue.

Il file MS Word (* .doc) è un file composto OLE2. Per non disturbarti con molti dettagli inutili, pensalo come un file system memorizzato in un file. In realtà utilizza la struttura FAT, quindi la definizione vale. (Hm, forse puoi montarlo in loop in Linux ???) In questo modo, puoi archiviare più file all'interno di un file, come immagini ecc. Lo stesso viene fatto in * .docx usando invece l'archivio ZIP. Ci sono pacchetti disponibili su PyPI in grado di leggere file OLE. Mi piace (olefile, compoundfile, ...) Ho usato il pacchetto compoundfiles per aprire il file * .doc. Tuttavia, in MS Word 97-2000, i file secondari interni non sono XML o HTML, ma file binari. E poiché ciò non è abbastanza, ognuno contiene informazioni sull'altro, quindi devi leggerne almeno due e svelare le informazioni memorizzate di conseguenza. Per comprendere appieno, leggi il documento PDF da cui ho preso l'algoritmo.

Il codice seguente è composto e testato in modo molto rapido su un numero limitato di file. Per quanto posso vedere, funziona come previsto. A volte appare un po 'incomprensibile all'inizio e quasi sempre alla fine del testo. E ci possono essere anche alcuni personaggi strani nel mezzo.

Quelli di voi che desiderano solo cercare un testo saranno felici. Tuttavia, esorto chiunque possa aiutare a migliorare questo codice a farlo.


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

Solo un'opzione per leggere i file 'doc' senza usare COM: miette . Dovrebbe funzionare su qualsiasi piattaforma.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top