前回の記事: ExtractContent を PHP で書き換えた | ごみばこいん Blog
「今回 PHP に書き換えてみた ExtractContent も含めて、これらの比較は次の記事でやりたい」といいつつ、他のネタが挟まり、ようやくにして比較しました。
比較した結論
- sters/extract-content - Packagist
- 非常に優秀。
- ぼくの作ったものが優秀という話ではなく、元々のロジックが優秀なんです。
- j0k3r/php-readability - Packagist
- どちらかというと情報量多めに取れることが多い
- scotteh/php-goose - Packagist
- 日本語サポートさえ行ければあり
- 今回の例だとまったく取れないサイトもあった
- 多言語混合だと厳しい
- zackslash/php-web-article-extractor - Packagist
- 日本語環境下においては厳しい
- php-goose のそれと同様で日本語って難しいよね、という話
お試しにはこちらのリポジトリをどうぞ。 sters/compare-article-extractors: Compare web article extractors.
日本語環境下で難しい話
php-goose 、または php-web-article-extractor では、どちらも内部にストップワード辞書を持っていて、プログラム上で言語を指定、あるいは lang 属性や meta タグから読み取った言語名から、適切なストップワード辞書を選択しています。そうして決まったストップワードの一覧が、文字列にどれくらいあるかを確認して、本文かどうか?といった判断を進めているようです。
ストップワードとはよく使われがちな単語のことで、自然言語処理の前処理として行なうことでデータ量を減らしたり、精度を上げたり出来ます。
例えば英語では「This is a pen.」といったようにスペースで区切られているので「ストップワードの is と a の 2 文字がある!こいつはコンテンツだ!」と簡単に出来るのですが、日本語の場合はそう簡単な話ではありません。日本語はスペース区切りではありませんし、前後にある文字によって、まったく異なる意味合いになったりもしますので、一概に辞書でドバーッと指定することは適切な処理でない可能性が高いです。
じゃあどうするかというと分かち書きの出番なのですが、分かち書きも簡単なものではありません。 Chasen や Mecab といった既存の技術を利用すればお手軽にもできますが php-goose や php-web-article-extractor がそれを利用して日本語対応するかというとちょっと違いそうだなあ、という気持ちです。
php-goose に出したプルリクは諦めてドバーッと処理する形ではありますが、日本語だけ特殊化せざるを得ないので、そうやってみて出してみたものの、なんだかなあと。いやそもそも 元になってる Goose はそういう実装になっていないだろうし…。
そのほかのアプローチ方法
DOM構造や、画面上の位置情報も利用するのはめっちゃ有効的だと思います。 PuppeteerでWebページからメインコンテンツっぽいところを抽出してみる - Qiita
上記の記事の「まとめ」でも出てはいますが、機械学習して取るようにするのもよさそうです。 seomoz/dragnet: Just the facts – web page content extraction