PHP で本文抽出したいよね、という話

この記事は公開されてから1年以上経過しており、最新の内容に追従できていない可能性があります。

前回の記事: ExtractContent を PHP で書き換えた | ごみばこいん Blog

「今回 PHP に書き換えてみた ExtractContent も含めて、これらの比較は次の記事でやりたい」といいつつ、他のネタが挟まり、ようやくにして比較しました。

比較した結論

お試しにはこちらのリポジトリをどうぞ。 sters/compare-article-extractors: Compare web article extractors.

日本語環境下で難しい話

php-goose 、または php-web-article-extractor では、どちらも内部にストップワード辞書を持っていて、プログラム上で言語を指定、あるいは lang 属性や meta タグから読み取った言語名から、適切なストップワード辞書を選択しています。そうして決まったストップワードの一覧が、文字列にどれくらいあるかを確認して、本文かどうか?といった判断を進めているようです。

ストップワードとはよく使われがちな単語のことで、自然言語処理の前処理として行なうことでデータ量を減らしたり、精度を上げたり出来ます。

自然言語処理における前処理の種類とその威力 - Qiita

例えば英語では「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

サイト案内

運営してるひと: @sters9

最近は Go, Ruby, Rails, Kubernetes, GCP, Datadog あたりをしていますがもっといろいろやりたい!

サイト案内

開発環境の紹介

プライバシーポリシー

tools.gomiba.co

サイト内検索

アーカイブ

2024/09 (3) 2024/07 (1) 2024/06 (3) 2024/05 (1) 2024/04 (7) 2024/03 (4) 2024/01 (3)

2023/12 (1) 2023/11 (3) 2023/10 (1) 2023/09 (1) 2023/08 (2) 2023/05 (4) 2023/04 (4) 2023/03 (4) 2023/02 (2) 2023/01 (1)

2022/12 (2) 2022/11 (4) 2022/10 (3) 2022/09 (2) 2022/08 (4) 2022/07 (5) 2022/06 (4) 2022/05 (9) 2022/04 (8) 2022/03 (10) 2022/02 (21) 2022/01 (8)

2021/12 (11) 2021/11 (1) 2021/10 (4) 2021/09 (2) 2021/08 (1) 2021/07 (2) 2021/06 (5) 2021/05 (10) 2021/04 (1) 2021/03 (8) 2021/02 (12) 2021/01 (8)

2020/05 (2) 2020/04 (2) 2020/02 (2) 2020/01 (1)

2019/12 (3) 2019/11 (2) 2019/10 (5) 2019/09 (3) 2019/07 (6) 2019/06 (4) 2019/04 (3) 2019/01 (2)

2018/12 (6) 2018/10 (4) 2018/09 (6) 2018/08 (7) 2018/07 (16) 2018/06 (7) 2018/05 (7) 2018/04 (5) 2018/03 (3) 2018/02 (10) 2018/01 (6)

2017/12 (8) 2017/11 (6) 2017/10 (10) 2017/09 (12) 2017/08 (12) 2017/07 (3) 2017/06 (1) 2017/01 (4)

2016/12 (5) 2016/10 (3) 2016/09 (1) 2016/07 (2) 2016/06 (1) 2016/04 (1) 2016/02 (1) 2016/01 (2)

2015/12 (1) 2015/10 (1) 2015/09 (3) 2015/06 (1) 2015/01 (1)

2014/08 (2) 2014/07 (3) 2014/05 (1) 2014/01 (7)

2013/12 (2) 2013/11 (4) 2013/10 (1) 2013/09 (1) 2013/08 (3) 2013/07 (4) 2013/06 (5) 2013/05 (2) 2013/04 (7) 2013/03 (1)