Deprecated:
この記事は非推奨です。
掲題の目的ならもっとカンタンな以下の方法で大丈夫。
https://qiita.com/arc279/items/5b6cf2d0b24ce5a50cae
試行錯誤の過程を残しておく目的で消さないけど、
以下はほとんどelasticsearchのingest-attachmentプラグインの紹介みたいな感じになってます。
なんか全文検索な本来の目的とは違うような気がするけど、副産物利用。
PDFMiner とかはちょっと構造が複雑になると全然駄目なので、ここはやはりApacheか…みたいな。
サンプルは 平成29年版 厚生労働白書 で試してみる。
wget http://www.mhlw.go.jp/wp/hakusyo/kousei/17/dl/all.pdf
結果をgistに置いときます。(1.6Mのテキストなのでけっこうでかい)
https://gist.github.com/arc279/21e5257b24cda1a652ff48601fc29366
考察とかは後述。
ぶっちゃけ「おぉっ!」ってなるほど精度は高くないけど、pdfのまま扱うよりテキストとして扱うほうが圧倒的に楽なので、
元のpdfと付き合わせながらテキストからコーパスを整えたりしていくといいんじゃないかと。
elasticsearch
ingest-attachment プラグインを使うといいらしい。
細かいところはよくわかってないけど、だいたい usage の通りでいけるはず。
ちなみに doc
とか xls
とか ppt
とかのOfficeファイルもいけるらしい。
本来の全文検索用途でも使える。
dockerでやる
名前は適当に。
FROM docker.elastic.co/elasticsearch/elasticsearch:6.0.1
LABEL maintainer "kuryu <revision279@gmail.com>"
RUN elasticsearch-plugin install analysis-icu
RUN elasticsearch-plugin install analysis-kuromoji
RUN elasticsearch-plugin install ingest-attachment
ビルドして、
docker build --no-cache -t kuryu/es kuryu-es-sample
起動。
version: '2.2'
services:
elasticsearch:
image: kuryu/es
container_name: elasticsearch
environment:
- cluster.name=dev-kuryu-cluster
- node.name=dev-kuryu-01
- log4j2.disable.jmx=true
- bootstrap.memory_lock=true
- "ES_JAVA_OPTS=-Xms1024m -Xmx1024m"
ulimits:
memlock:
soft: -1
hard: -1
nofile:
soft: 65536
hard: 65536
volumes:
- ./volumes/esdata1:/usr/share/elasticsearch/data
ports:
- 9200:9200
docker-compose up
実行
下準備
HOST='localhost:9200'
あと、毎回ヘッダ書くのがめんどくさいのでcurlの設定ファイル書いておく。
-s
-H "Content-Type: application/json"
-H "X-Config-File: .curlrc"
pipeline を設定
data
フィールドに生データを base64
して放り込めば my-attachment
パイプラインに流れるようにする。
curl -K .curlrc -XPUT "${HOST}/_ingest/pipeline/my-attachment?pretty" -d '
{
"description" : "Extract attachment information",
"processors" : [
{
"attachment" : {
"field" : "data",
"indexed_chars" : -1
}
}
]
}
'
{
"acknowledged" : true
}
pdfをbase64化して投入
data
フィールドに生データを base64
して放り込む。
cat <<-EOD | curl -K .curlrc -X POST "${HOST}/test-ingest/pdf/1?pipeline=my-attachment&pretty" -d @-
{
"data": "$(base64 -w 0 'all.pdf')"
}
EOD
{
"_index" : "test-ingest",
"_type" : "pdf",
"_id" : "1",
"_version" : 1,
"result" : "created",
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 0,
"_primary_term" : 1
}
結果を取り出す
curl -K .curlrc -XGET "${HOST}/test-ingest/pdf/1" > 1.json
でjsonで結果が返ってきて、 _source
の下に抽出された文章が入っているので、そこから jq
で抜き出す。
cat 1.json | jq -r ._source.attachment.content
で、
- 見出しとかキャプションとかは変なところで切れてしまったり、
- 図とか段組みは縦書きに認識されてしまったり、
- 全体的に図というか絵みたいになってるページはまるごとスルーされたり、
するけど、文章の塊はわりとしっかり抜けてる感じ。
pdfの中身は文書ではなくグラフみたいなもので、全く構造化されてないから最悪や、的なDISを見たことがあるけど、
ほんとその通りで真面目にやろうとすると大変つらい。
っていう話。
余談
どうやってpdfの中身抽出してるのか中身を追ってみたら
- elasticsearch
にたどり着いたので、
とりあえず手元のmacで
java -jar pdfbox-app-2.0.8.jar ExtractText a.pdf
とかやろうとしたら
Exception in thread "main" java.lang.UnsupportedOperationException: TTF fonts do not have a CFF table
とか出てこけた。
で、原因と思しきフォント周り調べてて危うく死にかけた。
TTFがOTFの流れを汲むCFFをType42がCIDFontType2だかなんだかで何言ってんのかさっぱりわからん。
https://fontforge.github.io/ja/cidmenu.html
http://blog.antenna.co.jp/PDFTool/archives/2006/05/pdf_24_cidkeyed.html
詳しくはこのあたりを見て、ぜひ「なにいってだこいつ」感を味わって頂きたい。
おわり。
余談の余談
というか、これ
Exception in thread "main" java.lang.UnsupportedOperationException: TTF fonts do not have a CFF table
が手元で解決できればわざわざelasticsearch経由しなくてもpdfbox単体でいけると思う。
#解決の目処が立ちそうになかったからelasticsearchにお願いしたので