Rubyによるクローラー開発技法のまとめ
クローラーとは
クローラー(Crawler)とは、Web上の文章や画像を自動的に収集してくれるプログラムのこと
もともとは、検索エンジン用にWebサイトをインデックス化するために作られた。Googleのボットが有名。
クローラー(Crawler)以外にもスパイダー(spider)やロボット(robot)等呼ばれる
クローラーの目的
Webサイトを巡回して取得した情報をデータベース化すること
クローラーの構成要素
クローラーは以下3つに分類される
1. コンテンツの取得(クローリング)
2. データの解析(スクレイピング)
3. データの保存
1.コンテンツの取得(クローリング)
HTMLをダウンロードして、そのHTMLに含まれるリンクを更に辿る。
リンク先としてはaタグやImgタグを辿る
2. データの解析(スクレイピング)
ダウンロードしたページの解析をして、
欲しい情報を抜き取る
以下の方法がある
- 正規表現を使う
- HTMLを構文解析する
- 取得したHTMLを構文解析(パーサー)するXPathを使って情報を抜き取る
- 正規表現表現で情報を取得することに比べて解析処理コストはかかる。が、簡潔にプログラムを記述できる
3. データの保存
取得した情報をファイルまたはデータベースに保存する
クローラを定期的に利用する場合はデータの保存は必須になる
Rubyの便利なライブラリ
Rubyにはクローラーを実行する上で便利なライブラリがある。
標準のライブラリもあればGemで公開されているものも
ダウンロード用のライブラリ
- open-uri (標準ライブラリ)
- httpclient
HTML構文解析用のライブラリ
- Nokogiri
クローラ用のフレームワーク
- anemone
nokogiriを使ったサンプル
#!/usr/bin/ruby
# About nokogiri
require 'open-uri'
require 'nokogiri'
#doc = Nokogiri.HTML(open("http://nokogiri.org/"))
doc = Nokogiri.HTML(open("http://www.homes.co.jp/"))
# ページに含まれるリンクを出力する
doc.css('a').each do |element|
puts element[:href]
end
# =>
# http://www.homes.co.jp/
# http://www.homes.co.jp/contents/no1/
# http://www.homes.co.jp/contents/abouthomes/
# http://www.homes.co.jp/contents/sitemap/
# http://www.homes.co.jp/callcenter/
# ...
# h2のテキストを出力する
doc2 = Nokogiri.HTML(open("http://www.homes.co.jp/"))
doc.xpath('//h2').each do |e|
puts e.text
end
# =>
# 住まいを探す
# 不動産のカテゴリ一覧
# 住まい探しをはじめる前に
# 住まいが決まったら
# 住まいをキレイに、快適に
# 今と未来のオーナーの方へ
# 不動産会社の方へ
# 住宅研究、データベース
# HOME'Sとつながろう
# Pick up!
anemoneを使った例
以下の数行で、指定したページから1階層下までのh2のテキストを取得してきてくれる。超便利。
#!/usr/bin/ruby
# About anemone
require 'anemone'
Anemone.crawl("http://www.homes.co.jp/", :delay => 3,:depth_limit => 1) do |anemone|
anemone.on_every_page do |page|
page.doc.xpath("//h2").each do |title|
puts title.text
end
end
end
クローラのお作法
大規模なサイトの場合1リクエスト3~5秒は間隔空けといた方が良いらしい。
中規模や小さめのサイトならもっと余裕を持たせる。
また、クローラの可否をrobots.txtで指示をしているので、
robots.txtを見て、クローラをするかどうかを判定するようにした方がよい
robots.txtについて
robots.txtとは、サイトの所有者がクローラに対して指示をするためのファイル。
検索エンジンに対して、クローラを禁止を指示できたりする。
ただし、強制力はない。ので、クローラをかける側はできるだけrobots.txtの内容に沿ってクローラをかけること
クローラの判定の可否にrobotexというライブラリが便利
#!/usr/bin/ruby
# About robotex
require 'robotex'
robotex = Robotex.new "Crawler"
p robotex.allowed?("http://www.yahoo.co.jp/") # => true
p robotex.allowed?("http://www.facebook.com/") # => true
p robotex.allowed?("http://www.homes.co.jp/") # => true