【问题标题】:Best way to extract text from a Word doc without using COM/automation?不使用 COM/自动化从 Word 文档中提取文本的最佳方法?
【发布时间】:2008-09-03 20:18:47
【问题描述】:

是否有一种合理的方法可以从不依赖于 COM 自动化的 Word 文件中提取纯文本? (这是部署在非 Windows 平台上的 Web 应用程序的一项功能 - 在这种情况下是不可协商的。)

Antiword 似乎是一个合理的选择,但似乎它可能会被放弃。

Python 解决方案是理想的,但似乎不可用。

【问题讨论】:

    标签: python ms-word


    【解决方案1】:

    (与extracting text from MS word files in python相同的答案)

    使用我本周制作的原生 Python docx 模块。以下是如何从文档中提取所有文本:

    document = opendocx('Hello world.docx')
    
    # This location is where most document content lives 
    docbody = document.xpath('/w:document/w:body', namespaces=wordnamespaces)[0]
    
    # Extract all text
    print getdocumenttext(document)
    

    Python DocX site

    100% Python,没有 COM,没有 .net,没有 Java,没有使用正则表达式解析序列化 XML。

    【讨论】:

    • 非常感谢您创建这个库。我知道你已经在 3 年前发布了这个,但是有没有办法使用你的库将 DOCX 文档转换为 HTML?干杯
    • @mikemaccana 也可以解析 .doc(不是 .docx)文件吗?
    • 请单独询问 .doc 文件。
    【解决方案2】:

    我为此使用 catdoc 或 antiword,只要给出最容易解析的结果即可。我已经将它嵌入到python函数中,所以它很容易从解析系统(用python编写)中使用。

    import os
    
    def doc_to_text_catdoc(filename):
        (fi, fo, fe) = os.popen3('catdoc -w "%s"' % filename)
        fi.close()
        retval = fo.read()
        erroroutput = fe.read()
        fo.close()
        fe.close()
        if not erroroutput:
            return retval
        else:
            raise OSError("Executing the command caused an error: %s" % erroroutput)
    
    # similar doc_to_text_antiword()
    

    catdoc 的 -w 开关关闭换行,顺便说一句。

    【讨论】:

    • 注意python 3 去掉了popen3,见docs.python.org/3/library/…
    • 值得注意的是,antiword 不适用于最新的 docx 格式。他们的网站声明他们支持“Word 2、6、7、97、2000、2002 和 2003”
    【解决方案3】:

    如果您只想从 Word 文件 (.docx) 中提取文本,则只能使用 Python 来完成。就像 Guy Starbuck 写的那样,您只需解压缩文件,然后解析 XML。受python-docx 的启发,我写了一个simple function 来做到这一点:

    try:
        from xml.etree.cElementTree import XML
    except ImportError:
        from xml.etree.ElementTree import XML
    import zipfile
    
    
    """
    Module that extract text from MS XML Word document (.docx).
    (Inspired by python-docx <https://github.com/mikemaccana/python-docx>)
    """
    
    WORD_NAMESPACE = '{http://schemas.openxmlformats.org/wordprocessingml/2006/main}'
    PARA = WORD_NAMESPACE + 'p'
    TEXT = WORD_NAMESPACE + 't'
    
    
    def get_docx_text(path):
        """
        Take the path of a docx file as argument, return the text in unicode.
        """
        document = zipfile.ZipFile(path)
        xml_content = document.read('word/document.xml')
        document.close()
        tree = XML(xml_content)
    
        paragraphs = []
        for paragraph in tree.getiterator(PARA):
            texts = [node.text
                     for node in paragraph.getiterator(TEXT)
                     if node.text]
            if texts:
                paragraphs.append(''.join(texts))
    
        return '\n\n'.join(paragraphs)
    

    【讨论】:

    • 一段很棒的代码!对你的博客的一个小注释,如果代码的背景不是黑色的,那将更具可读性。
    • 哦,谢谢你的评论。问题是我“破解”了一点 Github CSS,所以颜色与我的网站相匹配。但是当 Github 对他们的 CSS 进行更改时,我必须再次修补我的样式表,就像现在一样。不确定我会保留这种方法...
    【解决方案4】:

    使用 OpenOffice API、Python 和 Andrew Pitonyak's excellent online macro book 我设法做到了这一点。第 7.16.4 节是开始的地方。

    另一个无需屏幕即可工作的技巧是使用 Hidden 属性:

    RO = PropertyValue('ReadOnly', 0, True, 0)
    Hidden = PropertyValue('Hidden', 0, True, 0)
    xDoc = desktop.loadComponentFromURL( docpath,"_blank", 0, (RO, Hidden,) )
    

    否则,当您打开文档时,该文档会在屏幕上(可能在网络服务器控制台上)弹出。

    【讨论】:

      【解决方案5】:

      tika-python

      Apache Tika 库的 Python 端口,根据文档,Apache tika 支持从 1500 多种文件格式中提取文本。

      注意:它还可以与 pyinstaller

      完美配合

      使用 pip 安装:

      pip install tika
      

      示例:

      #!/usr/bin/env python
      from tika import parser
      parsed = parser.from_file('/path/to/file')
      print(parsed["metadata"]) #To get the meta data of the file
      print(parsed["content"]) # To get the content of the file
      

      官方链接GitHub

      【讨论】:

      • 我尝试了您的示例,它似乎尝试下载并启动 Java .jar 文件:“正在检索 search.maven.org/remotecontent?filepath=org/apache/tika/…
      • 按照这些步骤 1. 您可以从here 手动下载 tika 2. 然后从 \Lib\site-packages\tika 文件夹中打开 tika.py 并替换 TikaJarPath = os.getenv('TIKA_PATH' , "路径\到\tika-server.jar\文件夹") TikaJarPath = os.getenv('TIKA_PATH', "F:\Projects\python\tika")
      【解决方案6】:

      Open Office 有一个API

      【讨论】:

        【解决方案7】:

        对于 docx 文件,请查看 Python 脚本 docx2txt,网址为

        http://cobweb.ecn.purdue.edu/~kak/distMisc/docx2txt

        用于从 docx 文档中提取纯文本。

        【讨论】:

          【解决方案8】:

          This worked well 用于 .doc 和 .odt。

          它在命令行上调用 openoffice 将文件转换为文本,然后您可以简单地将其加载到 python 中。

          (似乎还有其他格式选项,尽管它们显然没有记录。)

          【讨论】:

          • openoffice 和 libreoffice 对于处理 MS 格式非常不利。
          【解决方案9】:

          老实说不要使用“pip install tika”,这是为单用户(一名开发人员在他的笔记本电脑上工作)而不是为多用户(多开发人员)开发的。

          在命令行中使用 Tika 的小类 TikaWrapper.py 足以满足我们的需求。

          你只需要用 JAVA_HOME 路径和 Tika jar 路径来实例化这个类,就是这样!它适用于许多格式(例如:PDF、DOCX、ODT、XLSX、PPT 等)。

          #!/bin/python
          # -*- coding: utf-8 -*-
          
          # Class to extract metadata and text from different file types (such as PPT, XLS, and PDF)
          # Developed by Philippe ROSSIGNOL
          #####################
          # TikaWrapper class #
          #####################
          class TikaWrapper:
          
              java_home = None
              tikalib_path = None
          
              # Constructor
              def __init__(self, java_home, tikalib_path):
                  self.java_home = java_home
                  self.tika_lib_path = tikalib_path
          
              def extractMetadata(self, filePath, encoding="UTF-8", returnTuple=False):
                  '''
                  - Description:
                    Extract metadata from a document
                  
                  - Params:
                    filePath: The document file path
                    encoding: The encoding (default = "UTF-8")
                    returnTuple: If True return a tuple which contains both the output and the error (default = False)
                  
                  - Examples:
                    metadata = extractMetadata(filePath="MyDocument.docx")
                    metadata, error = extractMetadata(filePath="MyDocument.docx", encoding="UTF-8", returnTuple=True)
                  '''
                  cmd = self._getCmd(self._cmdExtractMetadata, filePath, encoding)
                  out, err = self._execute(cmd, encoding)
                  if (returnTuple): return out, err
                  return out
          
              def extractText(self, filePath, encoding="UTF-8", returnTuple=False):
                  '''
                  - Description:
                    Extract text from a document
                  
                  - Params:
                    filePath: The document file path
                    encoding: The encoding (default = "UTF-8")
                    returnTuple: If True return a tuple which contains both the output and the error (default = False)
                  
                  - Examples:
                    text = extractText(filePath="MyDocument.docx")
                    text, error = extractText(filePath="MyDocument.docx", encoding="UTF-8", returnTuple=True)
                  '''
                  cmd = self._getCmd(self._cmdExtractText, filePath, encoding)
                  out, err = self._execute(cmd, encoding)
                  return out, err
          
              # ===========
              # = PRIVATE =
              # ===========
          
              _cmdExtractMetadata = "${JAVA_HOME}/bin/java -jar ${TIKALIB_PATH} --metadata ${FILE_PATH}"
              _cmdExtractText = "${JAVA_HOME}/bin/java -jar ${TIKALIB_PATH} --encoding=${ENCODING} --text ${FILE_PATH}"
          
              def _getCmd(self, cmdModel, filePath, encoding):
                  cmd = cmdModel.replace("${JAVA_HOME}", self.java_home)
                  cmd = cmd.replace("${TIKALIB_PATH}", self.tika_lib_path)
                  cmd = cmd.replace("${ENCODING}", encoding)
                  cmd = cmd.replace("${FILE_PATH}", filePath)
                  return cmd
          
              def _execute(self, cmd, encoding):
                  import subprocess
                  process = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
                  out, err = process.communicate()
                  out = out.decode(encoding=encoding)
                  err = err.decode(encoding=encoding)
                  return out, err
          

          【讨论】:

            【解决方案10】:

            以防万一有人想用 Java 语言做有 Apache poi api。 extractor.getText() 将从 docx 中提取平面文本。这是链接https://www.tutorialspoint.com/apache_poi_word/apache_poi_word_text_extraction.htm

            【讨论】:

              【解决方案11】:

              Texttract-Plus

              使用 textract-plus 可以从大多数文档扩展名中提取文本,包括 doc、docm、dotx 和 docx。 (它使用 antiword 作为 doc 文件的后端) refer docs

              安装-

              pip install textract-plus
              

              样本-

              import textractplus as tp
              text=tp.process('path/to/yourfile.doc')
              

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2018-02-23
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多