1. 概要

Apache Tikaは、Word、Excel、PDF、さらにはJPEGやMP4などのマルチメディアファイルなど、さまざまな種類のドキュメントからコンテンツとメタデータを抽出するためのツールキットです。

すべてのテキストベースおよびマルチメディアファイルは、共通のインターフェイスを使用して解析できるため、Tikaはコンテンツ分析用の強力で用途の広いライブラリになります。

この記事では、Apache Tikaの概要を紹介します。これには、解析APIと、ドキュメントのコンテンツタイプを自動的に検出する方法が含まれます。 このライブラリの操作を説明するために、実際の例も提供されます。

2. 入門

Apache Tikaを使用してドキュメントを解析するには、Mavenの依存関係が1つだけ必要です。

<dependency>
    <groupId>org.apache.tika</groupId>
    <artifactId>tika-parsers</artifactId>
    <version>1.17</version>
</dependency>

このアーティファクトの最新バージョンはここにあります。

3. パーサーAPI

ParserAPIはApacheTikaの心臓部であり、解析操作の複雑さを抽象化します。 このAPIは、次の1つのメソッドに依存しています。

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

このメソッドのパラメーターの意味は次のとおりです。

  • stream 解析対象のドキュメントから作成されたInputStreamインスタンス
  • handler 入力ドキュメントから解析された一連のXHTMLSAXイベントを受信するContentHandlerオブジェクト。 次に、このハンドラーはイベントを処理し、結果を特定の形式でエクスポートします
  • metadata パーサーの内外でメタデータプロパティを伝達するMetadataオブジェクト
  • context ParseContext インスタンスは、コンテキスト固有の情報を保持し、解析プロセスをカスタマイズするために使用されます

parse メソッドは、入力ストリームからの読み取りに失敗した場合は IOException をスローし、ストリームから取得したドキュメントを解析できない場合は TikaException をスローし、[X186X ]SAXExceptionハンドラーがイベントを処理できない場合。

ドキュメントを解析するとき、TikaはApachePOIやPDFBoxなどの既存のパーサーライブラリを可能な限り再利用しようとします。 その結果、ほとんどの Parser 実装クラスは、そのような外部ライブラリへの単なるアダプタです。

セクション5では、handlerおよびmetadataパラメーターを使用してドキュメントのコンテンツとメタデータを抽出する方法を説明します。

便宜上、ファサードクラス Tika を使用して、 ParserAPIの機能にアクセスできます。

4. 自動検出

Apache Tikaは、追加情報ではなく、ドキュメント自体に基づいて、ドキュメントのタイプとその言語を自動的に検出できます。

4.1. ドキュメントタイプの検出

ドキュメントタイプの検出は、単一のメソッドを持つDetectorインターフェイスの実装クラスを使用して実行できます。

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

このメソッドは、ドキュメントとそれに関連するメタデータを取得し、ドキュメントのタイプに関する最良の推測を説明するMediaTypeオブジェクトを返します。

検出器が依存する情報源はメタデータだけではありません。 検出器は、ファイルの先頭近くにある特別なパターンであるマジックバイトを利用したり、検出プロセスをより適切な検出器に委任したりすることもできます。

実際、検出器で使用されるアルゴリズムは実装に依存します。

たとえば、デフォルトの検出器は最初にマジックバイトで動作し、次にメタデータプロパティで動作します。 この時点でコンテンツタイプが見つからない場合は、サービスローダーを使用して、使用可能なすべての検出器を検出し、それらを順番に試します。

4.2. 言語検出

ドキュメントの種類に加えて、Tikaはメタデータ情報の助けがなくてもその言語を識別できます。

Tikaの以前のリリースでは、ドキュメントの言語はLanguageIdentifierインスタンスを使用して検出されていました。

ただし、 LanguageIdentifier は非推奨になり、Webサービスが優先されます。これは、 GettingStartedドキュメントでは明確にされていません。

言語検出サービスは、抽象クラスLanguageDetectorのサブタイプを介して提供されるようになりました。 Webサービスを使用して、Google翻訳やMicrosoftTranslatorなどの本格的なオンライン翻訳サービスにアクセスすることもできます。

簡潔にするために、これらのサービスについては詳しく説明しません。

5. アクションのティカ

このセクションでは、実際の例を使用してApacheTikaの機能を説明します。

イラストメソッドはクラスにラップされます:

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

クラスパスにtika.txtという名前の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();
}

ファイルの先頭にあるマジックバイト%PDF のおかげで、ファイル拡張子が間違っていても、Tikaが正しいメディアタイプを見つけられないことは明らかです。

便宜上、 Tika ファサードクラスを使用して検出コードを書き直すと、同じ結果になります。

public static String detectDocTypeUsingFacade(InputStream stream) 
  throws IOException {
 
    Tika tika = new Tika();
    String mediaType = tika.detect(stream);
    return mediaType;
}

5.2. コンテンツの抽出

次に、ファイルのコンテンツを抽出し、 Parser APIを使用して、結果をStringとして返します。

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

このコンテンツを含むクラスパスにMicrosoftWordファイルがあるとします。

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. メタデータの抽出

ドキュメントのコンテンツに加えて、 ParserAPIはメタデータを抽出することもできます。

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. 結論

このチュートリアルでは、ApacheTikaを使用したコンテンツ分析に焦点を当てました。 ParserAPIとDetectorAPIを使用して、ドキュメントのタイプを自動的に検出し、そのコンテンツとメタデータを抽出できます

高度なユースケースでは、カスタムParserおよびDetectorクラスを作成して、解析プロセスをより詳細に制御できます。

このチュートリアルの完全なソースコードは、GitHubにあります。