[PHP] PDFファイル内のテキストを抽出して、特定文字列を検索する処理

ネットワークサーバ上に置いてある大量のPDFファイルの中から、特定のキーワードが書かれているファイルのみを抽出したい、という依頼がありました。そんなこと無理だろう、と思ったけど、PDF内にテキストで書かれていれば、それを抽出してチェックできるんじゃないか、ということで、処理を考えてみました。

できないわけがない、の精神!(笑)

スポンサーリンク

今回処理を作成した環境

  • 抽出したいPDFファイルは、WindowsServer上で共有しているフォルダの中にある。
  • PDFから文字列を抽出するため、Linuxで使えるpdftotextというコマンドを使う。社内にはCentOS6サーバがあるので、ここに環境を構築する。
  • 処理はシェルスクリプトでもいいが、Windows上で操作できた方が楽なのでPHPで行う。PHPはCentOS6上で動かすものとし、Windowsからはブラウザでアクセスする。

まずはLinux側の設定から

PDFから文字列を抽出するため、Linuxで環境を構築する。まずは必要なモジュールのインストールから。

# yum install poppler poppler-utils

続いて、ネットワーク共有フォルダをマウントするために必要なモジュールの確認。

# rpm -q cifs-utils

インストールされていればOK。もしなかったら、インストール。

# yum install cifs-utils

ネットワーク共有フォルダをマウントする。そのまま/mntにマウントしてもいいが、今回は/mnt/serverにマウントする。

# mount -t cifs //192.168.1.250/共有 -o username=[USERNAME],password=[PASSWORD],r,nounix,iocharset=utf8,file_mode=0644,dir_mode=0755 /mnt/server

上記、//192.168.1.250/共有 の部分にマウントするネットワーク共有フォルダを指定。
その共有フォルダにアクセス権のあるユーザーとパスワードをそれぞれ[USERNAME]、[PASSWORD]に入れる。
その直後の「r」は読み込み専用の指定。書き込みも許可する場合は「rw」と書けば良い。
それ以外はそのまま記述してOK。最後にマウント先を指定して、Entrer!

これでLinux側の準備は整いました。

PHPで処理を書きます

PHPからのPDF読み込み等の操作は、通常のファイル操作をする場合と全く同じ。今回対象となるPDFは特定のフォルダの中で更に細分化されてフォルダに収められているので、フォルダの中を順番に開いてPDFファイルをチェックしていきます。

処理はこんな感じ。フォルダ名や検索文字等はダミーに置き換えています。

$current_dir = dirname( __FILE__ );
$base_dir = "/mnt/server/資料1/平成30年度";

$search_dirs = scandir( "{$base_dir}/" );
$excludes = array( '.', '..' );
$search_names = array( "検索文字1", "検索文字2", "検索文字3" );

foreach( $search_dirs as $search_dir ){
    $flag = false;
    if( in_array( $search_dir, $excludes ) ) continue;
    foreach( glob( "{$base_dir}/{$search_dir}/*.pdf" ) as $pdf_file ){
        $log_file = "{$current_dir}/log/{$search_dir}_".basename( $pdf_file, ".pdf" ).".log";
        $cmd = "pdftotext '{$pdf_file}' '{$log_file}'";
        exec( $cmd );
        foreach( $search_names as $grep ){
            $cmd = "cat '{$log_file}' | grep '{$grep}'";
            $text = array();
            exec( $cmd, $text );
            if( strlen( trim( $text[0] ) ) > 0 ){
                file_put_contents( "{$current_dir}/discovery.txt", "{$pdf_file}\n", FILE_APPEND|LOCK_EX );
                $flag = true;
                break;
            }
        }
        $cmd = "rm -f '{$log_file}'";
        exec( $cmd );
        if( $flag === true ) break;
    }
}

$base_dirに、マウントしたネットワーク共有フォルダの検索したいPDFが入っているパスを設定。$search_namesに検索したい文字列を配列で設定。

処理結果

この処理を走らせると、このPHPファイルと同じディレクトリに、discovery.txtという名前のテキストファイルが生成され、検索文字列が存在したPDFのフルパス名が1行ずつ保存されていきます。ブラウザからアクセスできる場所に置いておけば、Windows上からも簡単に処理を実行・確認することができます。

時間がない中で慌てて作った処理のため、エラーチェック等は行っていませんし、おかしな動きをする可能性もありますので、参考程度にどうぞ!

スポンサーリンク

この記事をシェア

アカウントをフォロー