Apache Tika文档内容抽取工具

官方文档

1.介绍

Tika 是一个内容抽取的工具集合 (a toolkit for text extracting) 。它集成了 POI 和 Pdfbox,并且为文本抽取工作提供了一个统一的界面。其次,Tika 也提供了便利的扩展 API,用来丰富其对第三方文件格式的支持。

2.依赖

tika-core包含Tika的核心接口和类,用于在不需要完整的parser工具集的情况下,通过下面配置添加maven依赖:

  <dependency>
    <groupId>org.apache.tikagroupId>
    <artifactId>tika-coreartifactId>
    <version>1.24version>
  dependency>

如果你希望使用tika解析文档(不仅仅是识别文档类型),可以通过下面配置添加依赖:

  <dependency>
    <groupId>org.apache.tikagroupId>
    <artifactId>tika-parsersartifactId>
    <version>1.24version>
  dependency>

请注意,添加此依赖项将向项目引入许多可传递的依赖项,包括tika core上的依赖项。您需要确保这些依赖项不会与现有项目依赖项冲突。可以在tika parsers目录中使用以下命令来获得所有依赖项的完整列表。

mvn dependency:tree | grep :compile

更多上下游工具:

  • tike-app
    Tika应用程序。将上述组件和所有外部解析器库组合成一个带有GUI和命令行界面的可运行jar。
  • tika-server
    Tika的JAX-RS REST服务应用,基于Jetty服务器运行Tika Rest服务。
  • tika-bundle
    Tika的一个OSGi包,它将tika解析器与非OSGified解析器库结合起来,使它们易于在OSGi环境中部署。
  • tika-eval
    Tika评估模块。命令行工具,用于评估Tika的输出或比较Tika或其他文本提取包的两个不同版本的输出。
  • 其他语言包装
    在另一种编程语言(如Julia或Python)中,有几个包装器可以使用Tika。

3.支持的文档格式

原文

  • HTML
  • XML
  • MS-office
  • ODF(OpenDocumentFormat)
  • iWorks(Numbers,Pages,Keynote)
  • WordPerfect
  • PDF
  • ePub
  • RTF(RichTextFormat)
  • 压缩文件(tar,ar,arj,cpio,dump,zip,7zip,gzip,bzip2,xz,lzma,z,pac200)
  • text
  • rss
  • audio
  • image
  • video
  • Java class
  • 源代码
  • mail
  • cad
  • font

完整列表

支持格式完整列表

4.处理流程

Apache Tika文档内容抽取工具_第1张图片

Tika对文档内容信息的解析处理的流程如下:Tika通过MimeType(MIME是MIME(Multipurpose Internet Mail Extensions)多用途互联网邮件扩展类型。是设定某种扩展名的文件用一种应用程序来打开的方式类型)来实现对一个文档的具体识别工作,通过Language identifier来识别语言。根据MimeType和Language identifier的识别结果,选择调用具体的Parser来解析文档。而处理则由ContentHandler接口来完成。其中parser负责解析具体的文档,当解析到需要进行处理的时候,调用具体的信息处理类中的contentHandler进行解析内容的处理。解析、处理后得到的结果作为返回的值。

另外,关于文档的元信息会在处理的过程中被解析,并保存在Metadata对象中。比如一个文档的最后编辑时间,最后的保存时间,标题,作者以及contentType等。这些信息对于用一些关键信息进行文档检索非常有用。

5.Parser API

原文

org.apache.tika.parser.Parser接口是Tika的核心接口。它隐藏了不同文件格式和解析库的复杂性,同时为客户端应用程序从各种文档中提取结构化文本内容和元数据提供了简单而强大的机制。所有这些都是通过一种方法实现的:

void parse(InputStream stream, ContentHandler handler, Metadata metadata,ParseContext context) throws IOException, SAXException, TikaException;

parse方法将要解析的文档和相关的元数据作为输入,并将结果输出为XHTML SAX事件和额外的元数据。parse context参数用于指定与任何单个文档无关的上下文信息(如当前本地)。导致这种设计的主要标准是:

  • Streamed parsing
    接口不需要客户端应用程序或解析器实现来将完整的文档内容保存在内存中或假脱机到磁盘。这使得即使是巨大的文档也可以在不需要过多资源的情况下被解析。

  • Structured content
    解析器实现应该能够在提取的内容中包含结构信息(标题、链接等)。例如,客户机应用程序可以使用这些信息来更好地判断解析文档的不同部分的相关性。

  • Input metadata
    客户端应用程序应该能够在要分析的文档中包含元数据,如文件名或声明的内容类型。解析器实现可以使用这些信息来更好地指导解析过程。

  • Output metadata
    除了文档内容之外,解析器实现还应该能够返回文档元数据。许多文档格式包含元数据,如作者的姓名,这些元数据可能对客户端应用程序有用。

  • Context sensitivity
    虽然Tika解析器的默认设置和行为在大多数用例中都应该很好地工作,但是仍然有一些情况需要对解析过程进行更细粒度的控制。在不破坏抽象层的情况下,将这种特定于上下文的信息注入解析过程应该很容易。

6.实例

6.1.使用Tika面板工具解析文档

Tika facade提供了许多非常快速和简单的方法来让Tika解析内容,并返回生成的纯文本.


public String parseToStringExample() throws IOException, SAXException,TikaException {
    Tika tika = new Tika();
    try (InputStream stream = ParsingExample.class.getResourceAsStream("test.doc")) {
        return tika.parseToString(stream);
    }
}

6.2.使用自动识别解析器

为了获得更多的控制,可以直接调用Tika解析器。最有可能的情况是,首先需要使用自动检测解析器,它会自动找出内容类型,然后调用适当的解析器。


public String parseExample() throws IOException, SAXException, TikaException {
    AutoDetectParser parser = new AutoDetectParser();
    BodyContentHandler handler = new BodyContentHandler();
    Metadata metadata = new Metadata();
    try (InputStream stream = ParsingExample.class.getResourceAsStream("test.doc")) {
        parser.parse(stream, handler, metadata);
        return handler.toString();
    }
}

6.3.选择不同的输出格式

使用Tika,您可以获得以多种不同格式返回的文件文本内容。它们可以是纯文本、html、xhtml、文件某一部分的xhtml等等,这是根据您提供给解析器的ContentHandler来控制的。

解析为纯文本

使用BodyContentHandler将文档内容转化为纯文本。


public String parseToPlainText() throws IOException, SAXException, TikaException {
    BodyContentHandler handler = new BodyContentHandler();
 
    AutoDetectParser parser = new AutoDetectParser();
    Metadata metadata = new Metadata();
    try (InputStream stream = ContentHandlerExample.class.getResourceAsStream("test.doc")) {
        parser.parse(stream, handler, metadata);
        return handler.toString();
    }
}

解析为XHTML

使用ToXMLContentHandler将文档内容转化为XHTML。


public String parseToHTML() throws IOException, SAXException, TikaException {
    ContentHandler handler = new ToXMLContentHandler();
 
    AutoDetectParser parser = new AutoDetectParser();
    Metadata metadata = new Metadata();
    try (InputStream stream = ContentHandlerExample.class.getResourceAsStream("test.doc")) {
        parser.parse(stream, handler, metadata);
        return handler.toString();
    }
}

如果只需要xhtml文档的body,而不需要header,可以将BodyContentHandler和ToXMLContentHandler链接在一起,如图所示:


public String parseBodyToHTML() throws IOException, SAXException, TikaException {
    ContentHandler handler = new BodyContentHandler(
            new ToXMLContentHandler());
 
    AutoDetectParser parser = new AutoDetectParser();
    Metadata metadata = new Metadata();
    try (InputStream stream = ContentHandlerExample.class.getResourceAsStream("test.doc")) {
        parser.parse(stream, handler, metadata);
        return handler.toString();
    }
}

只获取XHTML的某些内容

可以对解析结果执行XPath查询,只获取XHTML的某些位置。


public String parseOnePartToHTML() throws IOException, SAXException, TikaException {
    // Only get things under html -> body -> div (class=header)
    XPathParser xhtmlParser = new XPathParser("xhtml", XHTMLContentHandler.XHTML);
    Matcher divContentMatcher = xhtmlParser.parse("/xhtml:html/xhtml:body/xhtml:div/descendant::node()");
    ContentHandler handler = new MatchingContentHandler(
            new ToXMLContentHandler(), divContentMatcher);
 
    AutoDetectParser parser = new AutoDetectParser();
    Metadata metadata = new Metadata();
    try (InputStream stream = ContentHandlerExample.class.getResourceAsStream("test2.doc")) {
        parser.parse(stream, handler, metadata);
        return handler.toString();
    }
}

6.4.自定义Handler

使用Tika解析文件的文本输出通过传递给parse方法的SAX ContentHandler返回。可以通过提供自己的ContentHandler来定制解析,ContentHandler可以做一些特殊的事情。

将内容中的电话号码提取到元数据中

通过使用PhoneExtractingContentHandler,您可以在提取的文档文本内容中找到任何电话号码,并将其放入元数据对象中。

将纯文本分块流式处理

有时候,你想把得到的文本分块,也许是为了尽量减少内存使用,也许是为了输出到HDFS文件,或者是其他原因!通过一个小的自定义内容处理程序,您可以做到这一点。


public List<String> parseToPlainTextChunks() throws IOException, SAXException, TikaException {
    final List<String> chunks = new ArrayList<>();
    chunks.add("");
    ContentHandlerDecorator handler = new ContentHandlerDecorator() {
        @Override
        public void characters(char[] ch, int start, int length) {
            String lastChunk = chunks.get(chunks.size() - 1);
            String thisStr = new String(ch, start, length);
 
            if (lastChunk.length() + length > MAXIMUM_TEXT_CHUNK_SIZE) {
                chunks.add(thisStr);
            } else {
                chunks.set(chunks.size() - 1, lastChunk + thisStr);
            }
        }
    };
 
    AutoDetectParser parser = new AutoDetectParser();
    Metadata metadata = new Metadata();
    try (InputStream stream = ContentHandlerExample.class.getResourceAsStream("test2.doc")) {
        parser.parse(stream, handler, metadata);
        return chunks;
    }
}

6.5.翻译

Tika提供了一个可插入的翻译系统,允许您将解析结果发送到外部系统或程序,以便将文本翻译成另一种语言。

使用微软翻译api

为了使用Microsoft翻译API,您需要注册一个Microsoft帐户,获取一个API密钥,然后在翻译之前将密钥传递给Tika。


public String microsoftTranslateToFrench(String text) {
    MicrosoftTranslator translator = new MicrosoftTranslator();
    // Change the id and secret! See http://msdn.microsoft.com/en-us/library/hh454950.aspx.
    translator.setId("dummy-id");
    translator.setSecret("dummy-secret");
    try {
        return translator.translate(text, "fr");
    } catch (Exception e) {
        return "Error while translating.";
    }
}

语种识别

Tika通过LanguageIdentifier类提供了识别文本语种的支持。


public String identifyLanguage(String text) {
    LanguageIdentifier identifier = new LanguageIdentifier(text);
    return identifier.getLanguage();
}

6.6.更多例子

请阅读《实战Tika》,所有的例子都在SVN上的TikaExample模块。

你可能感兴趣的:(Java)