Анализ содержимого с помощью Apache Tika

Анализ содержимого с помощью Apache Tika

1. обзор

Apache Tika is a toolkit for extracting content and metadata from various types of documents, например Word, Excel и PDF, или даже мультимедийные файлы, такие как JPEG и MP4.

Все текстовые и мультимедийные файлы можно анализировать с помощью общего интерфейса, что делает Tika мощной и универсальной библиотекой для анализа контента.

В этой статье мы познакомим вас с Apache Tika, включая его API синтаксического анализа и то, как он автоматически определяет тип содержимого документа. Также будут приведены рабочие примеры, иллюстрирующие работу этой библиотеки.

2. Начиная

Для анализа документов с использованием Apache Tika нам нужна только одна зависимость Maven:


    org.apache.tika
    tika-parsers
    1.17

Последнюю версию этого артефакта можно найтиhere.

3. APIParser

The Parser API is the heart of Apache Tika, abstracting away the complexity of the parsing operations. Этот API опирается на один метод:

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

Значения параметров этого метода:

  • stream - экземплярInputStream, созданный из документа для анализа

  • handler объектContentHandler, получающий последовательность событий XHTML SAX, проанализированных из входного документа; этот обработчик затем обработает события и экспортирует результат в определенной форме.

  • metadata объектMetadata, передающий свойства метаданных в анализатор и из него

  • context экземплярParseContext, несущий контекстно-зависимую информацию, используемую для настройки процесса синтаксического анализа

Методparse выдаетIOException, если он не может прочитать из входного потока,TikaException, если документ, взятый из потока, не может быть проанализирован, иSAXException, если обработчик не может обработать событие.

При анализе документа Tika старается максимально использовать существующие библиотеки синтаксического анализатора, такие как Apache POI или PDFBox. В результате большинство классов реализацииParser являются просто адаптерами для таких внешних библиотек.

В разделе 5 мы увидим, как параметрыhandler иmetadata могут использоваться для извлечения содержимого и метаданных документа.

Для удобства мы можем использовать класс фасадаTika для доступа к функциям APIParser.

4. Автоопределение

Apache Tika может автоматически определять тип документа и его язык на основе самого документа, а не на основании дополнительной информации.

4.1. Определение типа документа

The detection of document types can be done using an implementation class of the Detector interface, который имеет единственный метод:

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

Этот метод принимает документ и связанные с ним метаданные, а затем возвращает объектMediaType, описывающий наилучшее предположение относительно типа документа.

Метаданные - не единственный источник информации, на который полагается детектор. Детектор также может использовать магические байты, которые представляют собой особый шаблон в начале файла, или делегировать процесс обнаружения более подходящему детектору.

Фактически алгоритм, используемый детектором, зависит от реализации.

Например, детектор по умолчанию работает сначала с магическими байтами, а затем со свойствами метаданных. Если тип контента на этом этапе не найден, он будет использовать загрузчик служб, чтобы обнаружить все доступные детекторы и попробовать их по очереди.

4.2. Обнаружение языка

В дополнение к типу документа, Tika также может идентифицировать свой язык даже без помощи метаданных.

В предыдущих выпусках Tika язык документа определялся с помощью экземпляраLanguageIdentifier.

ОднакоLanguageIdentifier устарел в пользу веб-сервисов, что не указано в документацииGetting Started.

Сервисы определения языка теперь предоставляются через подтипы абстрактного классаLanguageDetector. Используя веб-сервисы, вы также можете получить доступ к полноценным сервисам онлайн-перевода, таким как Google Translate или Microsoft Translator.

Для краткости мы не будем подробно останавливаться на этих услугах.

5. Тика в действии

Этот раздел иллюстрирует возможности Apache Tika с использованием рабочих примеров.

Методы иллюстрации будут помещены в класс:

public class TikaAnalysis {
    // illustration methods
}

5.1. Определение типов документов

Вот код, который мы можем использовать для определения типа документа, прочитанного изInputStream:

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();
}

Предположим, у нас есть PDF-файл с именемtika.txt в пути к классам. Расширение этого файла было изменено, чтобы попытаться обмануть наш инструмент анализа. Настоящий тип документа все еще может быть найден и подтвержден тестом:

@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();
}

Ясно, что неправильное расширение файла не может помешать Tika найти правильный тип носителя, благодаря волшебным байтам%PDF в начале файла.

Для удобства мы можем переписать код обнаружения, используя класс фасадаTika с тем же результатом:

public static String detectDocTypeUsingFacade(InputStream stream)
  throws IOException {

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

5.2. Извлечение содержимого

Давайте теперь извлечем содержимое файла и вернем результат в видеString - используя 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();
}

Учитывая файл Microsoft Word в classpath с этим содержанием:

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

Содержание может быть извлечено и проверено:

@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();
}

Опять же, классTika можно использовать для более удобного написания кода:

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

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

5.3. Извлечение метаданных

Помимо содержимого документа APIParser также может извлекать метаданные:

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;
}

Когда файл Microsoft Excel существует в пути к классам, этот тестовый пример подтверждает, что извлеченные метаданные верны:

@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();
}

Наконец, вот еще одна версия метода извлечения с использованием класса фасадаTika:

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

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

6. Заключение

Этот урок посвящен анализу контента с помощью 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.

Для расширенных вариантов использования мы можем создать собственные классыParser иDetector, чтобы иметь больший контроль над процессом синтаксического анализа.

Полный исходный код этого руководства можно найти наover on GitHub.