Análise de conteúdo com Apache Tika

Análise de conteúdo com Apache Tika

1. Visão geral

Apache Tika is a toolkit for extracting content and metadata from various types of documents, como Word, Excel e PDF ou mesmo arquivos multimídia como JPEG e MP4.

Todos os arquivos multimídia e baseados em texto podem ser analisados ​​usando uma interface comum, tornando o Tika uma biblioteca poderosa e versátil para análise de conteúdo.

Neste artigo, daremos uma introdução ao Apache Tika, incluindo sua API de análise e como ele detecta automaticamente o tipo de conteúdo de um documento. Também serão fornecidos exemplos de trabalho para ilustrar as operações desta biblioteca.

2. Começando

Para analisar documentos usando o Apache Tika, precisamos apenas de uma dependência do Maven:


    org.apache.tika
    tika-parsers
    1.17

A versão mais recente deste artefato pode ser encontradahere.

3. A APIParser

The Parser API is the heart of Apache Tika, abstracting away the complexity of the parsing operations. Esta API depende de um único método:

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

Os significados dos parâmetros deste método são:

  • stream uma instânciaInputStream criada a partir do documento a ser analisado

  • handler um objetoContentHandler recebendo uma seqüência de eventos XHTML SAX analisados ​​a partir do documento de entrada; este manipulador irá então processar eventos e exportar o resultado em um formulário particular

  • metadata um objetoMetadata transportando propriedades de metadados dentro e fora do analisador

  • context uma instânciaParseContext contendo informações específicas do contexto, usado para personalizar o processo de análise

O métodoparse lança umIOException se não consegue ler do fluxo de entrada, umTikaException se o documento retirado do fluxo não pode ser analisado e umSAXException se o manipulador não consegue processar um evento.

Ao analisar um documento, o Tika tenta reutilizar as bibliotecas do analisador existentes, como Apache POI ou PDFBox, tanto quanto possível. Como resultado, a maioria das classes de implementaçãoParser são apenas adaptadores para tais bibliotecas externas.

Na seção 5, veremos como os parâmetroshandleremetadata podem ser usados ​​para extrair conteúdo e metadados de um documento.

Por conveniência, podemos usar a classe de fachadaTika para acessar a funcionalidade da APIParser.

4. Auto-Detecção

O Apache Tika pode detectar automaticamente o tipo de documento e seu idioma com base no próprio documento, e não em informações adicionais.

4.1. Detecção de tipo de documento

The detection of document types can be done using an implementation class of the Detector interface, que possui um único método:

MediaType detect(java.io.InputStream input, Metadata metadata)
  throws IOException

Este método pega um documento e seus metadados associados - então retorna um objetoMediaType que descreve a melhor estimativa em relação ao tipo do documento.

Os metadados não são a única fonte de informação na qual um detector depende. O detector também pode usar bytes mágicos, que são um padrão especial próximo ao início de um arquivo ou delegar o processo de detecção a um detector mais adequado.

De fato, o algoritmo usado pelo detector depende da implementação.

Por exemplo, o detector padrão trabalha primeiro com bytes mágicos, depois com as propriedades de metadados. Se o tipo de conteúdo não foi encontrado neste ponto, ele usará o carregador de serviço para descobrir todos os detectores disponíveis e testá-los por sua vez.

4.2. Detecção de idioma

Além do tipo de documento, o Tika também pode identificar seu idioma mesmo sem a ajuda das informações de metadados.

Em versões anteriores do Tika, o idioma do documento é detectado usando uma instânciaLanguageIdentifier.

No entanto,LanguageIdentifier se tornou obsoleto em favor dos serviços da web, o que não está claro nos documentosGetting Started.

Os serviços de detecção de idioma agora são fornecidos por meio de subtipos da classe abstrataLanguageDetector. Usando serviços da Web, você também pode acessar serviços de tradução on-line completos, como o Google Translate ou o Microsoft Translator.

Por uma questão de brevidade, não examinaremos esses serviços em detalhes.

5. Tika em ação

Esta seção ilustra os recursos do Apache Tika usando exemplos de trabalho.

Os métodos de ilustração serão agrupados em uma classe:

public class TikaAnalysis {
    // illustration methods
}

5.1. Detectando Tipos de Documento

Aqui está o código que podemos usar para detectar o tipo de documento lido em umInputStream:

public static String detectDocTypeUsingDetector(InputStream stream)
  throws IOException {
    Detector detector = new DefaultDetector();
    Metadata metadata = new Metadata();

    MediaType mediaType = detector.detect(stream, metadata);
    return mediaType.toString();
}

Suponha que temos um arquivo PDF denominadotika.txt no classpath. A extensão deste arquivo foi alterada para tentar enganar nossa ferramenta de análise. O tipo real do documento ainda pode ser encontrado e confirmado por um teste:

@Test
public void whenUsingDetector_thenDocumentTypeIsReturned()
  throws IOException {
    InputStream stream = this.getClass().getClassLoader()
      .getResourceAsStream("tika.txt");
    String mediaType = TikaAnalysis.detectDocTypeUsingDetector(stream);

    assertEquals("application/pdf", mediaType);

    stream.close();
}

É claro que uma extensão de arquivo errada não pode impedir Tika de encontrar o tipo de mídia correto, graças aos bytes mágicos%PDF no início do arquivo.

Por conveniência, podemos reescrever o código de detecção usando a classe de fachadaTika com o mesmo resultado:

public static String detectDocTypeUsingFacade(InputStream stream)
  throws IOException {

    Tika tika = new Tika();
    String mediaType = tika.detect(stream);
    return mediaType;
}

5.2. Extraindo conteúdo

Vamos agora extrair o conteúdo de um arquivo e retornar o resultado comoString - usando a APIParser:

public static String extractContentUsingParser(InputStream stream)
  throws IOException, TikaException, SAXException {

    Parser parser = new AutoDetectParser();
    ContentHandler handler = new BodyContentHandler();
    Metadata metadata = new Metadata();
    ParseContext context = new ParseContext();

    parser.parse(stream, handler, metadata, context);
    return handler.toString();
}

Dado um arquivo do Microsoft Word no caminho de classe com este conteúdo:

Apache Tika - a content analysis toolkit
The Apache Tika™ toolkit detects and extracts metadata and text ...

O conteúdo pode ser extraído e verificado:

@Test
public void whenUsingParser_thenContentIsReturned()
  throws IOException, TikaException, SAXException {
    InputStream stream = this.getClass().getClassLoader()
      .getResourceAsStream("tika.docx");
    String content = TikaAnalysis.extractContentUsingParser(stream);

    assertThat(content,
      containsString("Apache Tika - a content analysis toolkit"));
    assertThat(content,
      containsString("detects and extracts metadata and text"));

    stream.close();
}

Novamente, a classeTika pode ser usada para escrever o código de forma mais conveniente:

public static String extractContentUsingFacade(InputStream stream)
  throws IOException, TikaException {

    Tika tika = new Tika();
    String content = tika.parseToString(stream);
    return content;
}

5.3. Extraindo Metadados

Além do conteúdo de um documento, a APIParser também pode extrair metadados:

public static Metadata extractMetadatatUsingParser(InputStream stream)
  throws IOException, SAXException, TikaException {

    Parser parser = new AutoDetectParser();
    ContentHandler handler = new BodyContentHandler();
    Metadata metadata = new Metadata();
    ParseContext context = new ParseContext();

    parser.parse(stream, handler, metadata, context);
    return metadata;
}

Quando um arquivo do Microsoft Excel existe no caminho de classe, este caso de teste confirma que os metadados extraídos estão corretos:

@Test
public void whenUsingParser_thenMetadataIsReturned()
  throws IOException, TikaException, SAXException {
    InputStream stream = this.getClass().getClassLoader()
      .getResourceAsStream("tika.xlsx");
    Metadata metadata = TikaAnalysis.extractMetadatatUsingParser(stream);

    assertEquals("org.apache.tika.parser.DefaultParser",
      metadata.get("X-Parsed-By"));
    assertEquals("Microsoft Office User", metadata.get("Author"));

    stream.close();
}

Finalmente, aqui está outra versão do método de extração usando a classe de fachadaTika:

public static Metadata extractMetadatatUsingFacade(InputStream stream)
  throws IOException, TikaException {
    Tika tika = new Tika();
    Metadata metadata = new Metadata();

    tika.parse(stream, metadata);
    return metadata;
}

6. Conclusão

Este tutorial focou na análise de conteúdo com o Apache Tika. Using the Parser and Detector APIs, we can automatically detect the type of a document, as well as extract its content and metadata.

Para casos de uso avançados, podemos criar classesParsereDetector personalizadas para ter mais controle sobre o processo de análise.

O código-fonte completo para este tutorial pode ser encontradoover on GitHub.