Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
Help us understand the problem. What is going on with this article?

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

More than 3 years have passed since last update.

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

はじめに

クローラー/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はちょっと大げさ過ぎる
  • 大規模なら選択肢としてアリかも(?)
lldev2
LL言語の開発に関する話題を紹介していく予定です。 特にオブジェクト指向に関する連載を予定しています。 予備知識がなくてもある程度は文脈で分かるように、 (詳しさよりも)分かりやすい文章を意識しています。 文章の割合が高いものははてなブログで、 コードの割合が高いものはQiita、質問と回答はTeratail、 とサービスを使い分けたいと思います。
http://dev2.hatenablog.jp/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away