Rubyでスパイダリングとかをやってみた

Ruby勉強会番外編っぽくスパイダリング講座on Webをやるとか書いてたので、深夜Ustreamでやってみました。結果としては教えるより、教えてもらうような感じになったけどねwww。

hpricotの付近からujihisaさんid:beatinaniwaさんに教えてもらいました、ありがとうございました。そういうわけで勉強したことをアウトプットとしてまとめておきたいと思います。「スパイダリングって何?」っていう人はだまされたと思ってやってみるといいと思うよ!!

簡単バージョン

基本的なライブラリを使ってやってみたバージョン。これはソースっぽいのをだだっーと出力するだけで、使いものになるかはあれだけど、スパイダリングの感覚っぽいのはつかめるんじゃないかと思います。

require 'net/http'
require 'iconv'

Net::HTTP.start('www.yahoo.co.jp', 80) {|http|
  response = http.get('/index.html')
  puts Iconv::iconv('euc-jp','UTF-8',response.body.to_s)
}
ポイント
  • そのまま出力しようとすると、文字化けが起きるのでiconvでごにょごにょする

RSSを取得

最近のWebには何でもRSSが付いてる感があるので、RSSの処理ができるといろいろ便利ですね。RubyにはRSSを処理するためのライブラリが最初からついていてよい感じ。TwitterもRSSを吐いているので、僕のRSSを取ってきて最近つぶやいたことを出力させてみた。

require 'rss'
require 'iconv'

rss = RSS::Parser.parse('http://twitter.com/statuses/user_timeline/3598791.rss')
rss.items.each{|item|
  puts Iconv::iconv('euc-jp','UTF-8',item.description.to_s)
}
ポイント
  • 「item.description.to_s」のところを「item.link.to_s」とかに変えるとpermalinkを持ってこれる
  • 必要なところに合せてそこを、変えてねということ

WWW::Mechanizeを使ったバージョン

クッキーとかログインが必要なページではPerlもWWW::Mechanize使うんだけど、Rubyでもそうらしい。でも、使いかたがちょっと分かりづらかったかな。。。

Yahoo!で「syou6162」を検索させてきて、そのページにあるリンクを全部出力させてみた、というやつです。

require 'rubygems'
require 'mechanize'
require 'iconv'
 
agent = WWW::Mechanize.new
page = agent.get('http://www.yahoo.co.jp/')
search_form = page.forms.with.name('sf1').first
search_form.p = 'syou6162'
search_results = agent.submit(search_form)

search_results.links.each do |link|
  puts link.href
end
ポイント
  • 「search_results.links」とか「link.href」ってのがよく分からんかったのだが、それぞれのオブジェクトのメソッド、ということらしい
    • htmlのタグにそれぞれ対応しているのかと思って、「search_results.div」とかやってはまってたってこと

hpricotを使ったバージョン

WWW::Mechanizeも便利なメソッドいっぱいそろっているんだけど、タイトルとかdivとかそういうのの抽出がよく分からなかった。そこでhpricotっていうのを教えてもらった。cssセレクターとかを使って持ってこれるらしい。cssセレクターが何かよく知らない僕でもできました><

WWW::Mechanizeのバージョンと同じようなことをさせて、検索結果ごとのタイトルっぽいのを引っ込ぬいてみた。

require 'rubygems'

require 'hpricot'
require 'open-uri'

query = "syou6162"

url = "http://search.yahoo.co.jp/search?p="+query+"&ei=UTF-8&fr=&rls=org.mozilla:ja-JP:unofficial"

doc = Hpricot( open(url).read )

(doc/"a.yschttl").each do |a|
  puts a.inner_text
end
ポイント
  • hpricotのメソッドとcssとの関係がよく分からなくてちょっとはまった
    • ここに詳しく載っているので見てみるとよいと思います
  • 「inner_text」メソッドを使うとhtmlのタグは自動的に除去されるらしいので、非常に素敵です

スパイダリングやりたいときに参考になる資料

下の二つの本はPerlとJavaの本だけど、スパイダリングやる際に必要になること、問題点、解決法などが分かるので、持っといて損はないかと思います。あ、あさましくなんてないんだからね><

Spidering hacks―ウェブ情報ラクラク取得テクニック101選

Spidering hacks―ウェブ情報ラクラク取得テクニック101選

Javaスパイダーツールサンプル&クックブック

Javaスパイダーツールサンプル&クックブック