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. API парсера
Parser
API — это сердце Apache Tika, позволяющее абстрагироваться от сложных операций синтаксического анализа . Этот API основан на одном методе:
void parse(
InputStream stream,
ContentHandler handler,
Metadata metadata,
ParseContext context)
throws IOException, SAXException, TikaException
Значения параметров этого метода:
stream
— экземплярInputStream
, созданный из документа для анализаобработчик
— объектContentHandler
, получающий последовательность событий XHTML SAX, проанализированных из входного документа; этот обработчик затем будет обрабатывать события и экспортировать результат в определенной формеметаданные
— объектметаданных
, передающий свойства метаданных в парсер и из него.context
— экземплярParseContext
, несущий контекстно-зависимую информацию, используемую для настройки процесса синтаксического анализа.
Метод parse
генерирует исключение IOException
, если ему не удается прочитать входной поток, исключение TikaException
, если документ, взятый из потока, не может быть проанализирован, и исключение SAXException
, если обработчик не может обработать событие.
При анализе документа Tika пытается максимально повторно использовать существующие библиотеки анализаторов, такие как Apache POI или PDFBox. В результате большинство классов реализации Parser
являются просто адаптерами для таких внешних библиотек.
В разделе 5 мы увидим, как можно использовать параметры обработчика
и метаданных для извлечения содержимого и метаданных документа.
Для удобства мы можем использовать фасадный класс Tika
для доступа к функциям Parser
API.
4. Автоматическое определение
Apache Tika может автоматически определять тип документа и его язык на основе самого документа, а не дополнительной информации.
4.1. Определение типа документа
Обнаружение типов документов можно сделать с помощью класса реализации интерфейса Detector
, который имеет единственный метод:
MediaType detect(java.io.InputStream input, Metadata metadata)
throws IOException
Этот метод принимает документ и связанные с ним метаданные, а затем возвращает объект MediaType
, описывающий наилучшее предположение относительно типа документа.
Метаданные — не единственный источник информации, на который опирается детектор. Детектор также может использовать магические байты, которые представляют собой специальный шаблон в начале файла, или делегировать процесс обнаружения более подходящему детектору.
На самом деле алгоритм, используемый детектором, зависит от реализации.
Например, детектор по умолчанию сначала работает с магическими байтами, а затем со свойствами метаданных. Если тип контента не был найден на этом этапе, он будет использовать загрузчик служб, чтобы обнаружить все доступные детекторы и попробовать их по очереди.
4.2. Обнаружение языка
Помимо типа документа, Tika также может определить его язык даже без помощи метаданных.
В предыдущих выпусках Tika язык документа определялся с помощью экземпляра LanguageIdentifier .
Однако LanguageIdentifier
устарел в пользу веб-служб, что не указано в документации по началу работы .
Службы определения языка теперь предоставляются через подтипы абстрактного класса 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. Извлечение контента
Давайте теперь извлечем содержимое файла и вернем результат в виде строки
, используя Parser
API:
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 в пути к классам с этим содержимым:
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. Извлечение метаданных
В дополнение к содержимому документа Parser
API также может извлекать метаданные:
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. Используя API-интерфейсы Parser
и Detector
, мы можем автоматически определять тип документа, а также извлекать его содержимое и метаданные .
Для расширенных вариантов использования мы можем создать собственные классы Parser
и Detector
, чтобы лучше контролировать процесс синтаксического анализа.
Полный исходный код этого руководства можно найти на GitHub .