Apache Tikaを使ってドキュメントの中身を取り出すPHPプログラム | A Day In The Boy's Life

A Day In The Boy's Life

とあるエンジニアのとある1日のつぶやき。

PHPというよりはSolrネタではあるのですが、Apache SolrにはApache Tikaというドキュメントのメタデータを抽出するソフトウェアが同梱されています。

Apache Tikaを使えば、WordやPowerPoint、PDFなど様々なドキュメントの本文を取り出し、それをApache Solrへ取り込んで検索対象にするといったことが可能になります。

利用イメージは下記のような感じで、今回のプログラムは赤枠の部分をするためのものです。


Apache Tikaを使ってSolrへインポート


今回利用しているApache Solrのバージョンは4.6.1、PHPは5.3系を使っています。



Apache Tikaからドキュメントのメタデータを抽出するPHPプログラム


Apache Solrの中にあるApache TikaへのアクセスはRESTなAPIが提供されているため、ここに示すPHPでなくても簡単なプログラムで利用可能です。

CURL関数を使って書いていますので、それこそ同様の処理をシェルスクリプトからとかでも作れたりします。


<?php

// Apache Solrが使うポート番号
$solrPort = "8983";

// Solrのコア名
$solrCore = "collection1";

// 実行ホストのドメイン
$domain = "localhost";

// Apache Solr(Tika)のURL
$solrUrl = "http://" . $domain . ":" . $solrPort . "/solr/" . $solrCore . "/update/extract?extractOnly=true";

if (empty($argv[1]) || !file_exists($argv[1])) {
    echo "ディレクトリが存在しません" . PHP_EOL;
    exit;
} else {
    $dir = $argv[1];
}

// cURL初期化、ヘッダ設定
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $solrUrl);
curl_setopt($curl, CURLOPT_BINARYTRANSFER, TRUE);
curl_setopt($curl, CURLOPT_POST, TRUE);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, TRUE);

if (is_dir($dir) && $dh = opendir($dir)) {
    while (($file = readdir($dh)) !== FALSE) {
        if ($file === "." || $file === "..") {
            continue;
        }
        // 読み込み対象ファイル
        $targetFile = $dir . $file;

        $data = array('name' => $targetFile, 'file' => '@' . $targetFile);
        curl_setopt($curl, CURLOPT_POSTFIELDS, $data);

        $result = curl_exec($curl);
        if (curl_errno($curl)) {
            $info = curl_getinfo($curl);
            if (empty($info['code'])) {
                $code = "ホストに通信できません";
            } else {
                $code = "HTTP Code:" . $info['code'];
            }
            $msg = "通信エラー: " . $code . " url:" . $info['url'];
            echo $msg . PHP_EOL;
            exit;
        }

        // 解析結果のXMLをパース
        $xml = simplexml_load_string($result);

        $body = strip_tags($xml->str);
        echo $targetFile . PHP_EOL;
        var_dump($body);
    }
    closedir($dh);
}


コマンドラインで動かす想定にしているため、第一引数にドキュメントが格納されているディレクトリを指定すればその中にあるファイルを拾ってApache Tikaへ投げ、解析結果を受け取るというような流れで動きます。

Solrのポート番号やコア名などは必要に応じて変更してください。


$ php import.php /path/to/docdata/

結果はXML形式で受け取っていますが(パラメータ無しの場合のデフォルト)Apache Solrの検索と同様にパラメータをつける事でJSON形式やCSVなどで受け取ることができたりします。


// Apache Solr(Tika)のURL
$solrUrl = "http://" . $domain . ":" . $solrPort . "/solr/" . $solrCore . "/update/extract?extractOnly=true&wt=json";

上記はJSON形式で結果を受け取りたい場合で、wtパラメータに所定の形式をセットしてAPIに問合せます。

受け取ったメタデータをその後、どう加工したいかで必要に応じて変えてみるのがよいのではないでしょうか。


ということで、Apache TikaへのAPIに対して、送信に必要な設定の上で抽出したいドキュメントデータをPOSTしてあげるだけで結果が受け取れます。

ドキュメントデータにパスワードがかけられているものもあったりしますので、そういう場合はHTTPステータスコードが500で返ってきたりしますので必要に応じてエラーハンドリングしておくのがよいでしょう。


PDFやWordなどオフィス系のファイルの中身を取り出してDBに格納したいとか、表示したいという場合に簡単に抽出ができるのでApache Tikaの利用を検討してみてもよいかもしれません。