Rubyでスクレイピングしてみました。

スクレイピングに挑戦したのでサンプルコードを公開。
スクレイピング楽しいね :laughing: 

Railsではなく素のRubyコードを書きました。
gemはbundlerでインストール。
bundlerでインストールしたgemを読み込む方法は[こちら](http://qiita.com/rinkun/items/e50c6fd3d5f89ef163a8)。

## mechanize編

最初に挑戦したのは`mechanize`というgem。
WEBサイトのインタラクションを自動化してくれるgemだそうです。
http://docs.seattlerb.org/mechanize/

今回は、[絵本ナビ](http://www.ehonnavi.net/)から、
「くすのきだんち」シリーズのタイトル一覧と表紙画像を取得して、
タイトルをターミナルに表示、画像をローカルに保存します。

では早速作業開始。

```
$ mkdir scraping
$ cd scraping
$ rbenv local 2.2.3
$ bundle init
$ vim Gemfile
// gem 'mechanize'と追記してください。

$ bundle install --path vendor/bundle
$ touch ehon.rb
```

```ruby:ehon.rb
# bundler経由でインストールしたgemを有効にするには下記のようにする
require 'bundler'
Bundler.require

# 検索したい絵本のタイトル　URL用に日本語をエンコーディングする必要あり
keyword = "くすのきだんち".encode("Shift_JIS")

# 「K」というパラメーターにkeywordを渡してやれば検索結果の一覧を表示できるみたい
target_url = "http://www.ehonnavi.net/ehon01.asp?sel=1&K=#{keyword}"

# 画像の格納ディレクトリ　なければ作る
dir_path = "./imgs"
FileUtils.mkdir_p(dir_path) unless FileTest.exist?(dir_path)

# スクレイピング用のコード
# クラス名'.detailOneCol'で絞り込んで、eachでまわしながら、
# 1件ずつタイトルを出力　画像は保存
agent = Mechanize.new
search_page = agent.get(target_url)
search_page.search('.detailOneCol').each do |item|
 puts title = item.search('div.text h3').inner_text # さらに絞り込み
 search_page.image_with(alt: "#{title}").fetch.save("#{dir_path}/#{title}.jpg") # altの値がtitleと一致しているので絞り込める
end
```

できたら、

```
$ ruby ehon.rb
```

わお！すごい :flushed: 
たったこれだけで望みが叶いました。

```ruby:scraping.rb
agent = Mechanize.new
search_page = agent.get('http://example.com')
p search_page.links[0].click
```

とすると、リンク先のページも取得できます。

```ruby:scraping.rb
agent = Mechanize.new
search_page = agent.get('http://example.com')
form = search_page.forms[0]
form.name = 'name'
form.password = 'secret'
p agent.submit(form)
```

とすると、フォームの項目を入力してサブミットした先のページを取得できます。

しかし、`mechanize`は普通に使うと、JavaScriptを実行できません。
あれっ、どうしよう :cold_sweat: 

## Capybara + Poltergeist(PhantomJS)編

クリックイベントなどJSを実行して動的にページを操作したい場合は、
ブラウザ上のアクションをシュミレートする`Capybara`と、
JavaScriptのドライバを組み合わせて実現します。

今回はドライバに`PhantomJS`を使用します。
さらにRubyからPhantomJSを扱えるように、`Poltergeist`というgemを導入します。

Capybara
https://github.com/jnicklas/capybara

Poltergeist
https://github.com/teampoltergeist/poltergeist

Gemfileに追記。

```
gem 'capybara'
gem 'poltergeist'
```

できたら、`bundle install`。

`PhantomJS`もインストールしてください。

```
$ brew install phantomjs
```

[バンダイチャンネル](http://www.b-ch.com/)から、「犬夜叉　第１期」全４４話の各話タイトルをターミナルに表示してみます。

http://www.b-ch.com/ttl/index.php?ttl_c=2277
にアクセスすると、ページの右側に「作品情報」が見えると思います。
下部のメニューから「各話あらすじ」のリンクをクリックすると、onClickイベントで第１話のタイトルとあらすじが表示されます。
「各話あらすじ」という見出しの下のページネーションをクリックしていくと、さらにonClickイベントで内容が書き換えられて、各話のタイトルとあらすじが確認できます。

これをCapybaraを使って、自動化すると下記のようになります。

```
$ touch bandai.rb
```

```ruby:bandai.rb
require 'bundler/setup'
require 'capybara/poltergeist'
Bundler.require

Capybara.register_driver :poltergeist do |app|
  Capybara::Poltergeist::Driver.new(app, {:js_errors => false, :timeout => 1000 })
end
session = Capybara::Session.new(:poltergeist)
session.visit "http://www.b-ch.com/ttl/index.php?ttl_c=2277"
puts session.status_code
puts '各話タイトル'

# 「各話あらすじ」をクリックする => onClickが実行される 
session.find('div.ttlinfo-menu').all('ul')[0].all('li')[2].find('a').click

# 第１話タイトル
puts session.find('div#ttlinfo-stry').find('dt').text

# 第２話タイトル〜
# 最終話は動的に取得してもよいかも
2.upto(44) do |num|
  # onClickイベント　ページネーションクリック
  session.find('div#ttlinfo-stry').find('p#page-list').click_link num.to_s
  sleep 3 # ajaxで内容が書き換えられる間少し待つ。待ち時間は適当...
  puts session.find('div#ttlinfo-stry').find('dt').text
end
```

```
$ ruby bandai.rb
```

また一つ望みが叶いました。
難しいことはまだまだですが、勉強になりました :smile: