JavaScriptを含むサイトをrubyでクロールしてみる

価格.comとかは製品一覧の表示をJavaScript使っているのでHpricotやMechanizeだけだと情報をとれないっぽい。
そこでrubyからIEを立ち上げてBotのようにIEを操作して情報を取得しているっぽいwatirというライブラリを試してみた。


やってることの流れとしては
watirを使用して「検索する」をクリック。情報の一覧のURLを取得する

Hpricotを利用して取得したURL先をクロールする

スペックのテーブル部分だけを引っ張ってきてhtmlに吐き出す
という感じです


検索オプションの設定や、「次へ」のクリックなどをはめんどくさいのではぶいてます。

require 'rubygems'
require 'watir'
require 'hpricot'
require 'open-uri'
require 'nkf'

#
# openするショートカットメソッド
#
def myopen url
  Hpricot(NKF.nkf("-s -xm0", open(url).read))
end

#
# IEを開いてjavascriptのリンク一覧を表示
#
ie = Watir::IE.new
ie.goto("http://kakaku.com/specsearch/0538/")
ie.button(:src, 'http://img.kakaku.com/images/spec_search/spec_submit.gif').click


#
# 製品情報のリンクだけ取得する
#
links = []
check = ""
ie.links().each do |l|
  line = l.to_s
  if /^href:\s*(http:\/\/kakaku.com\/item\/.*)/ =~ line
    l = ($1 + 'spec/').to_s
    next if check == l
    check = l
    links << l
  end
end

# もういらないので閉じる
ie.close()

#
# ディレクトリを作っておく
#
base_dir = "kakaku/"
css_dir = base_dir + "css/"
html_dir = base_dir + "html/"
[base_dir, css_dir, html_dir].each do |d|
  Dir.mkdir(d) unless File.exist?(d)
end

#
# 最初の一度だけCSS読み込み
#
def load_css doc, dir
  output = ""
  (doc/"link[@type='text/css']").map do |elem|
    link = elem[:href]
    name = link.scan(/.*\/(.*)$/).to_s

    open(dir + name, "w") do |f|
      open(link) do |data|
        f.puts data.read
      end
    end

    elem[:href] = "../css/" + name
    output += elem.to_html + "\n"
  end
end


#
# リンク先hpricotで読み込む
#
out_css = ""
out_items = ""
isCssLoad = false
links.each do |link|
  doc = myopen(link)
  if !isCssLoad
    out_css = load_css doc, css_dir
    isCssLoad = true
  end

  puts (doc/"div.floatL.mTop10 h3").inner_html + " を解析中"
  out_items += <<HTML
<p>
#{(doc/"div.h3Area").to_html}
#{(doc/:table).to_html}
</p>
<br /><hr/>
HTML
end

#
# output
#
open(html_dir + "index.html", "w") do |f|
  f.puts <<HTML
<html><head>
#{out_css}
</head>
<body>
#{out_items}
</body></html>
HTML
end