前回は既存のサイトにサイト内検索の機能を追加する方法を紹介しました。Fessにはさまざまな機能がありますが、今回と次回の2回に渡り、「Webスクレイピング」機能を紹介します。

Webスクレイピングとは?

近年、AIや機械学習は人気のある分野となっています。既に持っているデータを活用して新たな知見に繋げられるため、幅広い分野で活用できることが理由に挙げられます。

インターネット上には多くの情報がWebページの形かたちで公開されていますが、そこから情報を抽出する技術は「Webスクレイピング」と呼ばれています。このWebスクレイピングで情報を集め、機械学習を適用することで、情報収集の価値をあげることができます。

Fessには強力なクローラがあるので、Webページ内から指定した箇所を抽出して、インデックスに保存できます。Fessを利用することで、Webスクレイピングのプログラムを作成せずに、設定だけで必要な情報を収集して分析が可能になります。

それでは、ニュースサイトから情報を収集してテキストを分類するモデルについて説明していきます。

問題設定

例として、IT Search+の解説/事例記事を利用してテキスト分類モデルを作成することを考えていきます。

IT Search+の解説/事例記事には、「サーバ/ストレージ」などのカテゴリがあるので、任意の文章を与えたときにそれがどのカテゴリに属するのかを判定できる分類モデルを作成します。

また、問題設定を変えることで、スパム文書の判定やニュースアプリで利用しているような記事の自動振り分けなど、自然言語処理が関係するようなシステムも構築できます。

それでは、この問題設定でFessを利用したWebスクレイピングサーバの構築方法を説明します。

事前準備として、第1回の手順を参考にして、Fessをインストールしておいてください。

クロール対象の分析

Webスクレイピングをするためにはクロール対象を理解する必要があります。クロール対象がニュースサイトのような場合、一般的には、

  • 記事一覧ページ: URLはp=1やpage=1などのページ番号を含む
  • 記事ページ: …/article/<記事の名前>のような上位部分が同じ

の2種類のページをクロールして、後者だけを保存すれば必要な情報が収集できます。また、一覧ページはそのページ内にあるページネーションのリンクをクリックすれば、そのURLから判断できます。

次に記事ページから必要な箇所を抽出することを考えます。

Fessで普通にクロールするとbodyタグ以下のテキストが検索対象としてインデックスされるだけですが、Fessでは取得したい箇所をXPathで指定することでその値をインデックスに保存できます。

例えば、titleタグの値が欲しい場合は//TITLEと指定することで、値を抽出して保存します(FessではXPathのタグ名は大文字で指定する必要があります)。

クロール設定の作成

クロール対象と抽出箇所が決まれば、管理画面でクロール設定を作成します。今回のWebクロール設定は以下のようになります。

項目
名前 IT Search+ 解説/事例記事
URL https://news.mynavi.jp/itsearch/article/push_list/all
https://news.mynavi.jp/itsearch/article/push_list/all_2
https://news.mynavi.jp/itsearch/article/push_list/all_3
https://news.mynavi.jp/itsearch/article/push_list/all_4
https://news.mynavi.jp/itsearch/article/push_list/all_5
https://news.mynavi.jp/itsearch/article/push_list/all_6
https://news.mynavi.jp/itsearch/article/push_list/all_7
https://news.mynavi.jp/itsearch/article/push_list/all_8
https://news.mynavi.jp/itsearch/article/push_list/all_9
https://news.mynavi.jp/itsearch/article/push_list/all_10
クロール対象とするURL https://news.mynavi.jp/itsearch/article/push_list/all.*
https://news.mynavi.jp/itsearch/article/.*/[0-9]+
検索対象とするURL https://news.mynavi.jp/itsearch/article/.*/[0-9]+
設定パラメータ field.xpath.article_category=//LI[@class=’genre_tag sp-none’]/SPAN
field.xpath.article_body=//DIV[@class=’articleContent’]/P
config.html.canonical.xpath=
深さ 1
間隔 3000ミリ秒


まず、クロールを開始するために設定する一覧ページを確認します。一覧ページの2ページ目を確認すると、URLはall_2のようにページ番号を含む形式で指定されているので、各一覧ページのURLを設定します。

記事ページから記事ページへのリンクが存在する場合、検索の深さを指定しないと次々とクロールすることになるため、深さを1に制限することで、URLで指定された一覧ページ群から直接リンクされている記事ページだけを対象できます。

今回の設定は、一覧ページの10ページ目までにある記事をクロール対象にしています。

クロール対象とするURLを指定することで、一覧ページと記事ページだけをクロールするように制限しています。さらに、一覧ページは保存する必要がないため、検索対象とするURLで記事ページだけを保存するように指定しています。

今回は、記事ページ内からカテゴリ情報を取得してarticle_categoryフィールドに保存して、記事本文だけをarticle_bodyフィールドに保存する設定になっています。

Fessでは、field.xpath.[フィールド名]=[XPath]を設定パラメータに記述することで、指定したフィールド名で抽出した値をインデックスに保存できます。

サイトによっては一覧ページでcanonicalのURLが指定されている場合があり、FessはcanonicalのURLで処理しています。そのため、設定パラメータでconfig.html.canonical.xpathを空にすることで、canonicalの処理を無効にします。

有効期限の変更

Fessでは、クロール時にインデックスしたデータに、有効期限を設定しています。標準では3日が設定されているため、3日後には収集したデータが削除されます。削除されないようにするためには、管理画面から「全般」のクローラの設定で「以前のドキュメントを削除」の値を-1日に設定してください。

クロールの確認

ここまでの設定ができたら、「スケジューラ」のDefault Crawlerのジョブを開始して、クロールを実行します。クロールジョブの終了後、保存された値を確認します。Fessは追加したフィールドを標準で検索、表示できないように設定しています。今回、追加したarticle_categoryとarticle_bodyを取得するためには、app/WEB-INF/classes/fess_config.propertiesの以下のプロパティ値を変更します。

# JSPで記述して取得する場合
query.additional.response.fields=article_category,article_body
# JSONのレスポンスに含める場合
query.additional.api.response.fields=article_category,article_body

なお、fess_config.propertiesを変更後にFessを再起動する必要があります。再起動後に以下のようにJSON APIを呼び出すと値を取得できていることが確認できます。

$ curl -s "localhost:8080/json/?q=*" | /
 jq '.response.result[0] | {article_category: .article_category, article_body: .article_body[0:40]}'
{
 "article_category": "マーケティング",
 "article_body": "デジタル領域の4テーマについて、1日1テーマで開催された「Fujitsu Ins"
}

うまく取得できない場合は、logs/fess-crawler.logを参照して、クロールが期待通りに実行できているかなどを確認してください。

*  *  *

今回はFessをWebスクレイピングサーバとして利用する方法を紹介しました。 この機能を利用することで、スクレイピングのためのコードを書かずに設定だけで情報収集環境を構築することができ、本来の目的である分析や機械学習のタスクに注力することができると思います。

次回はFessで集めたデータを利用して、分類モデルを作成する方法を紹介します。

著者紹介

菅谷 信介 (Shinsuke Sugaya)

Apache PredictionIOにて、コミッター兼PMCとして活動。また、自身でもCodeLibs Projectを立ち上げ、オープンソースの全文検索サーバFessなどの開発に従事。