AdventCalendar
スクレイピング
クローラー

クローラー開発エッセンス

はじめに

クローラー/Webスクレイピング Advent Calendar 2017 - Qiita

「クローラー/Webスクレイピング Advent Calendar 2017」(上記リンク参照)に参加しています。

クローラーは、個々の技術は難しくないものの、用いられる技術が多岐に渡ります。そこで、開発のアイディアやノウハウを集めました。前半は入門、後半は、クローラーを運用する際のポイントを取り上げます。

なるべくコンパクトにエッセンスだけまとめるため、浅く広く箇条書きの記事になってしまいましたが、もし参考になれば幸いです。


クローラーを簡単に作る方法

まず、軽く小手調べというか、入門的な方法から書いていきましょう。
すでにバリバリ組んでいる読者の方は、ここを読み飛ばしてください。

ノンプログラミングコース

  • 一番簡単!
  • RSSリーダやWeb更新チェッカを使う
  • すでに完成したクローラーと見れなくもない
  • 自分で組まなくて済むコスパを考えると楽。とくにGUIがあるのが良い
  • 個人レベルでの運用や、実験的に少しデータを集めたい場合などに向く
  • とはいえ、取得ページが大量や定期的になるなら、やはり自動化したい
  • OPMLファイルをインポート/エクスポートすると、半自動化に使える

エクセル(VBA)コース

  • オフィスのエクセルでおなじみVBA
  • ExcelのVBAには「Webクエリ」という機能があり、Webにアクセスできる
  • だから、VBAでもクローラーが作れてしまう
  • じつは、エンジニアだと、VBAはかえって面倒に感じる(かも)
  • しかし、非エンジニアがVBAを習得しているケースで有効
  • 株価のように、結果を表に落とし込んで表計算する用途には相性が良い

シェル(スクリプト)コース

  • Linuxコマンドの「wget」を使う
  • Windowsでは?
  • PowerShellの「Invoke-WebRequest」がそれに相当する
  • もし、取ってくるページ数が少ない場合、小回りが利く
  • 大量のページを取得するなら、P言語で書きたい

P言語コース

  • メジャーな言語なら何でも、クローラーは作れる
  • ただあえて言えば、クローラー作成にはP言語がオススメ
  • P言語とは、Perl、PHP、Python、Rubyの4つ
  • Webとの親和性が高く、LLなので入門もしやすい
  • クローラー用ライブラリ/フレームワークがあって組むのが楽
  • 最近ではJavaScript(Node.js)のクローラーも有力になってきた様子

Ruby & RSSコース

  • 筆者がRubyを使用しているので、Rubyでの入門を解説する
  • Ruby標準ライブラリの「open-uri」と「rss」を使う
  • RSSはクロールするためにあるような規格なので楽
  • 構造が変わらない点で、HTMLを直接クロールするよりメンテが楽
  • だから、クローラーはRSSから入るのがオススメ
  • RSSの次は?
  • (Web)APIの取得がオススメ
  • APIを覚える必要はあるが、やはり構造が変わりにくいので楽
  • 本格的なクローラー制作には?
  • Rubyの場合、「Anemone」「Nokogiri」が定番ライブラリ
  • 『Rubyによるクローラー開発技法』がオススメの書籍(Rubyの場合)

クローラーの巡回戦略

後半は、クローラーの運用方法を書いていきます。

クロール規模が大きくなると、時間がかかって終わらなくなったりするため、
大量にクローリングする必要がある場合の巡回戦略から紹介します。

アクセスの複数同時化

  • まず、法的リスクからも「1秒ルール」は守るべきなので、待機時間の短縮には限界がある
  • そこで、別サイトに複数同時アクセスし、単位時間あたりの取得ページを増やす
  • その際、ドメインをリスト化して、同一ドメインの複数同時アクセスを禁止する
  • しかし、見落としがちだが、別ドメインでも、バックエンドのサーバは同一の場合もある
  • よって、別ドメインでも、同IPなら複数同時アクセスを禁止する方が、より無難

更新頻度のチェック

  • 巡回時に、ページが更新されているかどうかをチェックする
  • そして、ページの更新頻度の高さに比例してクロールする
  • すると、更新頻度が低いページを飛ばせるのでムダが少ない
  • 更新頻度を判定する具体的なアルゴリズムは?
  • たとえば、「2ちゃんねる」型のスレッドフロート掲示板がイメージしやすい
  • 更新されるたびにリストの先頭に追加していくと、更新頻度の高いものが浮上する
  • そこで、そのリスト前半のクロール頻度を高くし、後半を低くする
  • より正確にするなら、更新数と期間から「勢い」のような値を算出する
  • 難しくなるが、確率的モデルを追求すれば、さらに最適化できるかも(?)

並列処理と分散処理

ここでは、クローリング処理の並列化、分散化について書きます。
そもそもインターネットが分散型システムなので、
クローラーの処理を分散させるのも有効でしょう。

並列処理

  • クローラーの処理時間は、相手サーバとの通信にかなり割かれる
  • すると、CPUが遊んでしまうので、並列処理が有効
  • たとえば、クロールと、取得したページの解析処理を並行して進める
  • 取得するページが多ければ、マシン(と回線)を複数でクロールする
  • しかし、小規模だと複数のサーバを用意するのが大変
  • そこで、「AWS Lambda」のようなクラウドを利用する手もある

P2Pクローラー

  • 複数台の場合、ネットワークをP2Pの通信方式で並列化する手法もある
  • P2P共有ソフトがファイルを共有するのに対して、ページを共有するイメージ
  • サーバ/クライアント式のようなボトルネックができないのがメリット
  • 安価なマシンで台数が多い構成が取れるのもメリット
  • デメリットはプログラムが難しくなること
  • たとえば、各ノードが自律協調的にAIで判断し、ページを取得、選別するとか
  • 技術的には面白いが、難しい
  • 小規模にP2Pはちょっと大げさ過ぎる
  • 大規模なら選択肢としてアリかも(?)