JavaScript等を用いた動的ページをスクレイピングするためのライブラリSeleniumのRubyでの使い方


# Webサイトのスクレイピングに便利なSelenium

Webサイトの情報を収集する際によく使われる主砲にはMechanizeというライブラリを用いた手法がよく紹介されており、関連する記事や本が多数あります。

[Rubyによるクローラー開発技法 巡回・解析機能の実装と21の運用例](https://www.amazon.co.jp/Ruby%E3%81%AB%E3%82%88%E3%82%8B%E3%82%AF%E3%83%AD%E3%83%BC%E3%83%A9%E3%83%BC%E9%96%8B%E7%99%BA%E6%8A%80%E6%B3%95-%E5%B7%A1%E5%9B%9E%E3%83%BB%E8%A7%A3%E6%9E%90%E6%A9%9F%E8%83%BD%E3%81%AE%E5%AE%9F%E8%A3%85%E3%81%A821%E3%81%AE%E9%81%8B%E7%94%A8%E4%BE%8B-%E4%BD%90%E3%80%85%E6%9C%A8-%E6%8B%93%E9%83%8E/dp/4797380357?tag=kowalik-22)
<a rel="nofollow" href="https://www.amazon.co.jp/Ruby%E3%81%AB%E3%82%88%E3%82%8B%E3%82%AF%E3%83%AD%E3%83%BC%E3%83%A9%E3%83%BC%E9%96%8B%E7%99%BA%E6%8A%80%E6%B3%95-%E5%B7%A1%E5%9B%9E%E3%83%BB%E8%A7%A3%E6%9E%90%E6%A9%9F%E8%83%BD%E3%81%AE%E5%AE%9F%E8%A3%85%E3%81%A821%E3%81%AE%E9%81%8B%E7%94%A8%E4%BE%8B-%E4%BD%90%E3%80%85%E6%9C%A8-%E6%8B%93%E9%83%8E/dp/4797380357?tag=kowalik-22"><img border="0" src="http://ecx.images-amazon.com/images/I/51n148-dVtL.jpg" width=300></a>

しかし、問題は最近のWebサイトの多くはJavaScriptを多用した動的なサイトで、Mechanizeでは一部対応できないことです。そこで登場するのが動的サイトに対応したスクレイピング手法です。この記事ではSeleniumの使い方を紹介します。

# 前提環境
- Macbook pro, OS 10.11.5
- 言語: Ruby
- irb上で進めていきます
- Google webブラウザをインストールする必要あり(補足参照)

# Seleniumの使い方
今回は例としてtwitter.comにアクセスした時、左下に表示されるトレンドタグの取得方法を見ていきます。

![Kobito.hz19SM.png](https://qiita-image-store.s3.amazonaws.com/0/37217/f67c2c3a-c568-f97f-daf4-3b0af607bd44.png "Kobito.hz19SM.png")

＊より詳しい使い方は[公式ドキュメント](http://docs.seleniumhq.org/docs/)をご覧ください。

## インストール
itermやターミナル上で以下コマンドを叩きます。
`$ gem install selenium-webdriver`

これで準備完了です。
`$ irb`
を叩いてRubyを試せる環境に行きましょう。

```
> require 'selenium-webdriver'
=> true

> driver = Selenium::WebDriver.for(:chrome)
=> #<Selenium::WebDriver::Driver:0x11747e36fed8b568 browser=:chrome>

> url = "https://twitter.com/"
=> "https://twitter.com/"

> driver.get(url)
=> nil

> username_element = driver.find_element(:xpath => "//*[@id=\"signin-email\"]")
=> #<Selenium::WebDriver::Element:0x1b281e59c986bf82 id="0.5584925940159373-1">

> email_element.send_keys("twitter_username") # ここは自分のtwitterアカウントのユーザーネームを入れてください
=> nil

> password_element = driver.find_element(:xpath => "//*[@id=\"signin-password\"]")
=> #<Selenium::WebDriver::Element:0x15b13312080e2094 id="0.5584925940159373-2">

> password_element.send_keys("your_password")   # ここはtwitterアカウントのパスワードを入力
=> nil

> button_element = driver.find_element(:xpath => "//*[@id=\"front-container\"]/div[2]/div[2]/form/table/tbody/tr/td[2]/button")
=> #<Selenium::WebDriver::Element:0x..fdf0b7767475cc5ba id="0.5584925940159373-3">

> button_element.click   # twitterにログインできます！
=> nil

> driver.find_element(:xpath => "//*[@id=\"page-container\"]/div[1]/div[3]/div/div/div[2]/ul/li[1]/a/span[1]")
=> #<Selenium::WebDriver::Element:0x..fd5b9a3feddff8506 id="0.37072282307666615-1">

> trend_tag = driver.find_element(:xpath => "//*[@id=\"page-container\"]/div[1]/div[3]/div/div/div[2]/ul/li[1]/a/span[1]")
=> #<Selenium::WebDriver::Element:0x..fd5b9a3feddff8506 id="0.37072282307666615-1">

> trend_tag.text
=> "#プレミアム女子会"
``` 

# Seleniumの弱点
今回は手軽なのでSeleniumを使用しましたが、使ってみて幾つか弱点があることに気がつきました。

- 遅い
	- ページを一回一回レンダリングするのでとても時間がかかります。使っている途中でStackoverflowに質問したところ、PhantomJSを使ったほうが早いし、セットアップも簡単との情報がありました。PhantomJSをためしてみるのもいいかもしれません。
- ローカルで動かすのとサーバー上で動かすのに環境が違う
- chrome driverのインストールが面倒


## 補足
### Chrome Driverのインストール
Chromeの場合、Chrome Driverというソフトウェアをダウンロードする必要があります。以下の手順でダウンロードしましょう。
1. 最新版を[こちら](http://chromedriver.storage.googleapis.com/index.html)からダウンロードして解凍。
2. ターミナル上で `echo $PATH`をしてPATHをチェック
3. 1でダウンロードしたdriverをPATH上に置きます。
	例: `$ mv ~/Downloads/chromedriver /usr/local/bin`


【参考記事】
https://www.qoosky.io/techs/71dd2d67ea