«1. Обзор
Apache Tika — это набор инструментов для извлечения содержимого и метаданных из различных типов документов, таких как Word, Excel и PDF, или даже мультимедийных файлов, таких как JPEG и MP4.
Все текстовые и мультимедийные файлы можно анализировать с помощью общего интерфейса, что делает Tika мощной и универсальной библиотекой для анализа контента.
В этой статье мы познакомимся с Apache Tika, в том числе с его API синтаксического анализа и с тем, как он автоматически определяет тип содержимого документа. Также будут предоставлены рабочие примеры для иллюстрации работы этой библиотеки.
2. Начало работы
Для анализа документов с помощью Apache Tika нам нужна только одна зависимость Maven:
<dependency>
<groupId>org.apache.tika</groupId>
<artifactId>tika-parsers</artifactId>
<version>1.17</version>
</dependency>
Последнюю версию этого артефакта можно найти здесь.
3. Parser API
Parser API — это сердце Apache Tika, позволяющее абстрагироваться от сложности операций синтаксического анализа. Этот API основан на одном методе:
void parse(
InputStream stream,
ContentHandler handler,
Metadata metadata,
ParseContext context)
throws IOException, SAXException, TikaException
Значения параметров этого метода следующие:
-
поток — экземпляр InputStream, созданный из обработчика документа для анализа — объект ContentHandler, получающий последовательность События XHTML SAX, проанализированные из входного документа; затем этот обработчик будет обрабатывать события и экспортировать результат в метаданные определенной формы — объект метаданных, передающий свойства метаданных в контексте синтаксического анализатора и из него — экземпляр ParseContext, несущий контекстно-зависимую информацию, используемую для настройки процесса синтаксического анализа ~ ~~ Метод parse генерирует исключение IOException, если ему не удается прочитать входной поток, исключение TikaException, если документ, взятый из потока, не может быть проанализирован, и исключение SAXException, если обработчик не может обработать событие.
При анализе документа Tika пытается максимально повторно использовать существующие библиотеки анализаторов, такие как Apache POI или PDFBox. В результате большинство классов реализации Parser являются просто адаптерами для таких внешних библиотек.
В разделе 5 мы увидим, как можно использовать параметры обработчика и метаданных для извлечения содержимого и метаданных документа.
Для удобства мы можем использовать фасадный класс Tika для доступа к функциям Parser API.
4. Автоматическое определение
Apache Tika может автоматически определять тип документа и его язык на основе самого документа, а не дополнительной информации.
4.1. Обнаружение типа документа
Обнаружение типов документов может быть выполнено с помощью класса реализации интерфейса Detector, который имеет единственный метод:
Этот метод берет документ и связанные с ним метаданные — затем возвращает объект MediaType, описывающий наилучшее предположение относительно типа документа.
MediaType detect(java.io.InputStream input, Metadata metadata)
throws IOException
Метаданные — не единственный источник информации, на который опирается детектор. Детектор также может использовать магические байты, которые представляют собой специальный шаблон в начале файла, или делегировать процесс обнаружения более подходящему детектору.
На самом деле алгоритм, используемый детектором, зависит от реализации.
Например, детектор по умолчанию сначала работает с магическими байтами, а затем со свойствами метаданных. Если тип контента не был найден на этом этапе, он будет использовать загрузчик служб, чтобы обнаружить все доступные детекторы и попробовать их по очереди.
4.2. Определение языка
Помимо типа документа, Tika также может определить его язык даже без помощи метаданных.
В предыдущих выпусках Tika язык документа определялся с помощью экземпляра LanguageIdentifier.
Однако LanguageIdentifier устарел в пользу веб-сервисов, что не указано в документации по началу работы.
Службы определения языка теперь предоставляются через подтипы абстрактного класса LanguageDetector. Используя веб-службы, вы также можете получить доступ к полноценным службам онлайн-перевода, таким как Google Translate или Microsoft Translator.
Для краткости мы не будем подробно останавливаться на этих сервисах.
5. Tika в действии
В этом разделе показаны возможности Apache Tika на рабочих примерах.
«Методы иллюстрации будут заключены в класс:
5.1. Определение типов документов
public class TikaAnalysis {
// illustration methods
}
Вот код, который мы можем использовать для определения типа документа, прочитанного из InputStream:
Предположим, у нас есть файл PDF с именем tika.txt в пути к классам. Расширение этого файла было изменено, чтобы попытаться обмануть наш инструмент анализа. Реальный тип документа все еще может быть найден и подтвержден тестом:
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();
}
Понятно, что неправильное расширение файла не может помешать Tika найти правильный тип носителя, благодаря магическим байтам %PDF в начало файла.
@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, с тем же результатом:
5.2. Извлечение содержимого
public static String detectDocTypeUsingFacade(InputStream stream)
throws IOException {
Tika tika = new Tika();
String mediaType = tika.detect(stream);
return mediaType;
}
Теперь давайте извлечем содержимое файла и вернем результат в виде строки с помощью Parser API:
Учитывая файл Microsoft Word в пути к классам с этим содержимым:
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();
}
~ ~~ Содержимое можно извлечь и проверить:
Apache Tika - a content analysis toolkit
The Apache Tika™ toolkit detects and extracts metadata and text ...
Опять же, класс Tika можно использовать для более удобного написания кода:
@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();
}
5.3. Извлечение метаданных
public static String extractContentUsingFacade(InputStream stream)
throws IOException, TikaException {
Tika tika = new Tika();
String content = tika.parseToString(stream);
return content;
}
В дополнение к содержимому документа Parser API также может извлекать метаданные:
Если в пути к классам существует файл Microsoft Excel, этот тест подтверждает правильность извлеченных метаданных: ~ ~~
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;
}
Наконец, вот еще одна версия метода извлечения с использованием класса фасада Tika:
@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();
}
6. Заключение
public static Metadata extractMetadatatUsingFacade(InputStream stream)
throws IOException, TikaException {
Tika tika = new Tika();
Metadata metadata = new Metadata();
tika.parse(stream, metadata);
return metadata;
}
Это руководство посвящено анализу контента с помощью Apache Tika. Используя API-интерфейсы Parser и Detector, мы можем автоматически определять тип документа, а также извлекать его содержимое и метаданные.
Для расширенных вариантов использования мы можем создать собственные классы Parser и Detector, чтобы иметь больший контроль над процессом синтаксического анализа.
Полный исходный код этого руководства можно найти на GitHub.
«