extrayendo texto de archivos MS Word en Python

para trabajar con archivos de MS Word en python, hay extensiones win32 de python, que se pueden usar en windows. ¿Cómo hago lo mismo en linux? ¿Hay alguna biblioteca?

Podrías hacer una llamada de subproceso a antiword . Antiword es una utilidad de línea de comandos de Linux para descargar texto de un documento de Word. Funciona bastante bien para documentos simples (obviamente pierde formato). Está disponible a través de apt, y probablemente como RPM, o puede comstackrlo usted mismo.

Utilice el módulo docx de Python nativo . Aquí es cómo extraer todo el texto de un documento:

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

Ver el sitio de Python DocX

También puedes ver Textract que saca mesas, etc.

El análisis de XML con expresiones regulares invoca a cthulu. No lo hagas

La respuesta de Benjamin es bastante buena. Acabo de consolidarme …

 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 puede tener secuencias de comandos con Python: vea aquí .

Ya que OOo puede cargar la mayoría de los archivos de MS Word sin problemas, yo diría que es su mejor apuesta.

Sé que esta es una pregunta antigua, pero recientemente intenté encontrar una forma de extraer texto de archivos de MS Word, y la mejor solución que encontré fue con wvLib:

http://wvware.sourceforge.net/

Después de instalar la biblioteca, usarla en Python es bastante fácil:

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

Y eso es. Más o menos, lo que estamos haciendo es usar la función commands.getouput para ejecutar un par de scripts de shell, a saber, wvText (que extrae texto de un documento de Word y cat para leer el archivo). Después de eso, todo el texto del documento de Word estará en la variable out, listo para usar.

Esperemos que esto ayude a cualquiera que tenga problemas similares en el futuro.

Eche un vistazo a cómo funciona el formato de documento y cree un documento de Word usando PHP en Linux . El primero es especialmente útil. Abiword es mi herramienta recomendada. Aunque hay limitaciones :

Sin embargo, si el documento tiene tablas complicadas, cuadros de texto, hojas de cálculo incrustadas, etc., es posible que no funcione como se espera. Desarrollar buenos filtros de MS Word es un proceso muy difícil, así que por favor, tenga paciencia con nosotros mientras trabajamos para que los documentos de Word se abran correctamente. Si tiene un documento de Word que no se carga, abra un error e incluya el documento para que podamos mejorar el importador.

(Nota: también publiqué esto en esta pregunta , pero parece relevante aquí, así que por favor, disculpe la publicación).

Ahora, esto es bastante feo y bastante intrépido, pero parece funcionar para mí en la extracción de texto básica. Obviamente, para usar esto en un progtwig Qt tendrías que generar un proceso para él, etc., pero la línea de comandos que he hackeado juntos es:

 unzip -p file.docx | grep '//g' | grep -v '^[[:space:]]*$' 

Así que eso es:

descomprimir -p archivo.docx : -p == “descomprimir a la salida estándar

grep ‘ : tome solo las líneas que contienen ‘ es el elemento XML de Word 2007 para “texto”, por lo que puedo decir)

sed ‘s / <[^ <] > // g’ *: Eliminar todo dentro de las tags

grep -v ‘^ [[: space:]] $’ *: Eliminar líneas en blanco

Probablemente haya una forma más eficiente de hacer esto, pero parece funcionar para mí en los pocos documentos con los que lo he probado.

Que yo sepa, descomprimir, grep y sed tienen puertos para Windows y cualquiera de los Unixes, por lo que debería ser razonablemente multiplataforma. A pesar de ser un truco feo;)

Si su intención es utilizar módulos puramente python sin llamar a un subproceso, puede usar el modo 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 

Sin embargo, la cadena de contenido debe limpiarse; una forma de hacerlo es:

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

Pero seguramente hay una forma más elegante de limpiar la cadena, probablemente usando el módulo re. Espero que esto ayude.

Unoconv también podría ser una buena alternativa: http://linux.die.net/man/1/unoconv

Si tiene instalado LibreOffice, simplemente puede llamarlo desde la línea de comandos para convertir el archivo en texto y luego cargar el texto en Python.

No estoy seguro de si vas a tener mucha suerte sin usar COM. El formato .doc es ridículamente complejo, y a menudo se lo denomina “volcado de memoria” de Word al momento de guardar.

En Swati, eso está en HTML, que está bien y elegante, pero la mayoría de los documentos de Word no son tan buenos.

Para leer Word 2007 y archivos posteriores, incluidos los archivos .docx, puede usar el paquete python-docx :

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

Para leer archivos .doc de Word 2003 y versiones anteriores, realice una llamada de subproceso a antiword . Necesitas instalar antiword primero:

 sudo apt-get install antiword 

Entonces simplemente llámalo desde tu script de 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)) 

¿Es esta una vieja pregunta? Creo que tal cosa no existe. Solo hay respuestas y sin respuesta. Esta es bastante sin respuesta, o la mitad de la respuesta si lo desea. Bueno, todos los métodos para leer documentos * .docx (MS Word 2007 y posteriores) sin usar interoperabilidad COM están cubiertos. Pero los métodos para extraer texto de * .doc (MS Word 97-2000), usando solo Python, carecen de. ¿Es esto complicado? Hacer: no realmente, entender: bueno, eso es otra cosa.

Cuando no encontré ningún código terminado, leí algunas especificaciones de formato y saqué algunos algoritmos propuestos en otros idiomas.

El archivo MS Word (* .doc) es un archivo compuesto OLE2. Para no molestarle con muchos detalles innecesarios, considérelo como un sistema de archivos almacenado en un archivo. En realidad, utiliza la estructura FAT, por lo que la definición se mantiene. (Hm, tal vez pueda montarlo en Linux ???) De esta manera, puede almacenar más archivos dentro de un archivo, como imágenes, etc. Lo mismo se hace en * .docx utilizando el archivo ZIP en su lugar. Hay paquetes disponibles en PyPI que pueden leer archivos OLE. Me gusta (archivo, archivos compuestos, …) Utilicé el paquete de archivos compuestos para abrir el archivo * .doc. Sin embargo, en MS Word 97-2000, los subarchivos internos no son XML o HTML, sino archivos binarios. Y como esto no es suficiente, cada uno contiene información sobre el otro, por lo que debe leer al menos dos de ellos y desentrañar la información almacenada en consecuencia. Para comprender completamente, lea el documento PDF del cual tomé el algoritmo.

El código a continuación está compuesto y probado muy apresuradamente en una pequeña cantidad de archivos. Por lo que puedo ver, funciona según lo previsto. A veces, aparece algo incomprensible al principio, y casi siempre al final del texto. Y puede haber algunos personajes extraños en el medio también.

Aquellos de ustedes que solo deseen buscar texto estarán felices. Sin embargo, insto a cualquiera que pueda ayudar a mejorar este código para que lo haga.

 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 una opción para leer archivos ‘doc’ sin usar COM: miette . Debería funcionar en cualquier plataforma.