How can I search a word in a Word 2007 .docx file?

PythonMs WordOpenxmlDocx

Python Problem Overview


I'd like to search a Word 2007 file (.docx) for a text string, e.g., "some special phrase" that could/would be found from a search within Word.

Is there a way from Python to see the text? I have no interest in formatting - I just want to classify documents as having or not having "some special phrase".

Python Solutions


Solution 1 - Python

After reading your post above, I made a 100% native Python docx module to solve this specific problem.

# Import the module
from docx import *

# Open the .docx file
document = opendocx('A document.docx')

# Search returns true if found    
search(document,'your search string')

The docx module is at https://python-docx.readthedocs.org/en/latest/

Solution 2 - Python

More exactly, a .docx document is a Zip archive in OpenXML format: you have first to uncompress it.
I downloaded a sample (Google: some search term filetype:docx) and after unzipping I found some folders. The word folder contains the document itself, in file document.xml.

Solution 3 - Python

In this example, "Course Outline.docx" is a Word 2007 document, which does contain the word "Windows", and does not contain the phrase "random other string".

>>> import zipfile
>>> z = zipfile.ZipFile("Course Outline.docx")
>>> "Windows" in z.read("word/document.xml")
True
>>> "random other string" in z.read("word/document.xml")
False
>>> z.close()

Basically, you just open the docx file (which is a zip archive) using zipfile, and find the content in the 'document.xml' file in the 'word' folder. If you wanted to be more sophisticated, you could then parse the XML, but if you're just looking for a phrase (which you know won't be a tag), then you can just look in the XML for the string.

Solution 4 - Python

A problem with searching inside a Word document XML file is that the text can be split into elements at any character. It will certainly be split if formatting is different, for example as in Hello World. But it can be split at any point and that is valid in OOXML. So you will end up dealing with XML like this even if formatting does not change in the middle of the phrase!

<w:p w:rsidR="00C07F31" w:rsidRDefault="003F6D7A">

<w:r w:rsidRPr="003F6D7A">

<w:rPr>

<w:b /> 

</w:rPr>

<w:t>Hello</w:t> 

</w:r>

<w:r>

<w:t xml:space="preserve">World.</w:t> 

</w:r>

</w:p>

You can of course load it into an XML DOM tree (not sure what this will be in Python) and ask to get text only as a string, but you could end up with many other "dead ends" just because the OOXML spec is around 6000 pages long and MS Word can write lots of "stuff" you don't expect. So you could end up writing your own document processing library.

Or you can try using Aspose.Words.

It is available as .NET and Java products. Both can be used from Python. One via COM Interop another via JPype. See Aspose.Words Programmers Guide, Utilize Aspose.Words in Other Programming Languages (sorry I can't post a second link, stackoverflow does not let me yet).

Solution 5 - Python

You can use docx2txt to get the text inside the docx, than search in that txt

npm install -g docx2txt
docx2txt input.docx # This will  print the text to stdout

Solution 6 - Python

A docx is just a zip archive with lots of files inside. Maybe you can look at some of the contents of those files? Other than that you probably have to find a lib that understands the word format so that you can filter out things you're not interested in.

A second choice would be to interop with word and do the search through it.

Solution 7 - Python

a docx file is essentially a zip file with an xml inside it.
the xml contains the formatting but it also contains the text.

Solution 8 - Python

OLE Automation would probably be the easiest. You have to consider formatting, because the text could look like this in the XML:

<b>Looking <i>for</i> this <u>phrase</u>

There's no easy way to find that using a simple text scan.

Solution 9 - Python

You should be able to use the MSWord ActiveX interface to extract the text to search (or, possibly, do the search). I have no idea how you access ActiveX from Python though.

Solution 10 - Python

You may also consider using the library from OpenXMLDeveloper.org

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionGerryView Question on Stackoverflow
Solution 1 - PythonmikemaccanaView Answer on Stackoverflow
Solution 2 - PythonPhiLhoView Answer on Stackoverflow
Solution 3 - PythonTony MeyerView Answer on Stackoverflow
Solution 4 - PythonromeokView Answer on Stackoverflow
Solution 5 - Pythonedi9999View Answer on Stackoverflow
Solution 6 - PythonkokosView Answer on Stackoverflow
Solution 7 - PythonshooshView Answer on Stackoverflow
Solution 8 - PythonilitiritView Answer on Stackoverflow
Solution 9 - PythonAndy BriceView Answer on Stackoverflow
Solution 10 - PythonbillbView Answer on Stackoverflow