LightTableでRuby、Nokogiriを使ってリアルタイムスクレイピング

Light TableではREPLの機能を使うことができ、リアルタイムに式を評価しながらコードを書くことができます。

[LightTable - Light TableでリアルタイムExcelパース (Light Tableの使い方 第2章) - Qiita](http://qiita.com/kawasima/items/b8d7ca569c9d6315870b) の記事を読み、スクレイピングにも向いてそうだと思ったので、Ruby、Nokogiriを使って試してみます。

インストール時点ではClojure、Python、JavaScriptなどがREPLの機能を使うことができますが、Rubyは含まれていません。Rubyでは、プラグインをインストールすることでREPLが利用できるようになります。

# 環境準備
## プラグインのインストール

`Ctrl + Space` でコマンドパレットを表示し、 `Plugins: Show plugin manager` から **Ruby Instarepl** をインストールします。

Ruby Instareplについての詳細は以下を参照してください。

* [existentialmutt/lt-ruby](https://github.com/existentialmutt/lt-ruby)

![install_instarepl_ruby.JPG](https://qiita-image-store.s3.amazonaws.com/0/6092/68e0bc72-bf16-95a1-6ef0-73e7b8d675f0.jpeg)

インストール後、 `App: Reload Behaviors` コマンドを実行し、リロードします。

(Light Tableの再起動でもOK)

## Gemのインストール

Ruby Instarepl に必要なGemをインストールします。

```bash
$ gem install eventmachine
$ gem install json
$ gem install method_source
```

ついでに、スクレイピングで利用する[Nokogiri](http://nokogiri.org/)もインストールしておきます。

```bash
$ gem install nokogiri
```

自身はWindows 7 64bitで環境を構築しました。DevKitを入れる必要があったり、eventmachineが入らなかったり、nokogiriが入らなかったりとイロイロ面倒だったので、参考程度にリンクを貼っておきます。

* [Development Kit · oneclick/rubyinstaller Wiki](https://github.com/oneclick/rubyinstaller/wiki/Development-Kit)
* [Windows 7 に ruby 2.0 x64 を その5 ～EventMachine の問題と対策～｜Ruby と iPhone と UI と](http://uisteven.blog.fc2.com/blog-entry-49.html)
* [Windows 7 に Ruby 2.0 x64 を その1 ～Nokogiri が入らない問題と対策～｜Ruby と iPhone と UI と](http://uisteven.blog.fc2.com/blog-entry-36.html)

# コードを書く

## REPL機能を試す

ワークスペースに適当な名前でフォルダを作成し、コードを書いていきましょう。今回は、qiitaで自分がストックした投稿をスクレイピングしてみます。

![create_folder.jpg](https://qiita-image-store.s3.amazonaws.com/0/6092/c6429610-2406-4353-6b5a-292266146833.jpeg)

と、コードを書き始める前に、インストールしたプラグインの機能を利用しましょう。
コマンドパレットから `Ruby Instarepl: Toggle live mode` を選択します。

![toggle_live_mode.jpg](https://qiita-image-store.s3.amazonaws.com/0/6092/addd3404-fe15-33f9-ed59-2faa0852be14.jpeg)

live modeが有効になっていると、コードを書いた途端に式が評価されていきます。
live modeが無効になっていたり、うまく評価されない場合は `Ctrl + Enter` で該当行を評価することができます。

![instarepl.gif](https://qiita-image-store.s3.amazonaws.com/0/6092/3ec4ffb2-eaa7-b8b6-a80e-8a6d9813415e.gif)

凄い！便利！！

## スクレイピングのコードを書く

Instareplを使ってどのようにコードを作成したのか、実際のコード作成時の流れを追って説明します。

`doc = Nokogiri::HTML.parse(html, nil, charset)` で全要素を取得します。Instareplを起動しているので、以下のように要素の中身が表示されます。
![doc.png](https://qiita-image-store.s3.amazonaws.com/0/6092/549e9cad-d667-4ca2-c8b8-2956394540f0.png)


次に、ChromeのDeveloper ToolsでDOMを確認し、ザックリ `doc.xpath('//div[@class="activities"]')` で要素を取り出してみました。

画面上だとこの部分です。
![activities.png](https://qiita-image-store.s3.amazonaws.com/0/6092/7b9e871b-4583-44dd-200f-b03e3587f483.png)

Light Table上では以下のように表示されています。
![activities_nodes.png](https://qiita-image-store.s3.amazonaws.com/0/6092/8802ac2c-32f8-d6f3-6af1-40bb9c7eaa11.png)


その後、 `doc.xpath('//div[@class="activities"]').length` で1件しか取得出来ていないことを確認し、中身とDOMを見て `doc.xpath('//div[@class="activities"]/article')`  に変更しました。
(ホントにザックリ全体しか取れてませんでしたね！)

一応、 `.length`を付けて件数を表示し、20と表示されたので記事の要素が取得できていることが確認できます。
![article_length.png](https://qiita-image-store.s3.amazonaws.com/0/6092/87bbc0b6-6e05-254c-41f6-6c6161e3ef8c.png)

20件分のタイトルを表示したいのですが、まずは1件で試してみます。
![article_first_h1.png](https://qiita-image-store.s3.amazonaws.com/0/6092/a0931fe6-01f0-5066-3a19-80a63f4d4660.png)

実際は、 `.first` で1件取得し、 `.css('h1')` でタイトル部分の要素を取得し、 `.inner_text`でテキストを表示…と少しづつ試しました。Instareplでの表示では文字化けしてしまったので、`puts` でコンソールに出力するようにしています。

最後に、20件分の記事の要素が詰まったオブジェクト(Nokogiri::XML::NodeSet)に対し、eachでそれぞれのタイトルを表示するように記述して完成です。(1ページ目しかやっていないですが…)

最終的なコードは以下になります。Proxy環境下で行ったため設定が入っていますが、不要の場合は削除して構いません。

```rb
require 'open-uri'
require 'nokogiri'
 
# proxy設定
proxy = "http://YOUR_PROXY:8080"
proxy_user = "PROXY_USER"
proxy_pass = "PROXY_PASS"
options = { proxy_http_basic_authentication: [proxy, proxy_user, proxy_pass] }
 
# スクレイピング先のURL
url = 'http://qiita.com/tenten0213/stock'
 
charset = nil
html = open(url, options) do |f|
  charset = f.charset
  f.read
end
 
doc = Nokogiri::HTML.parse(html, nil, charset)
doc.xpath('//div[@class="activities"]/article').each do |node|
  puts node.css('h1').inner_text
end
```

https://gist.github.com/tenten0213/9524714

![print_result.png](https://qiita-image-store.s3.amazonaws.com/0/6092/34691694-5984-974f-b3bc-ae47f1746b69.png)

普段はirbやpryなどで値やオブジェクトを確認しながらコードを書いているのですが、Light Tableを使うとIDE上で同時に行えて便利です。

今回のようなWebページのスクレイピングや、参考にした記事のようにExcelパースをする場合、値を確認しながらコードを書けるのでとても便利だと思います。
便利そうだと感じた人は是非、試してみてください。