ElixirでMechanize1は使えないかと検索してみたが見つからない。
他に代わりになるようなライブラリは無いかと探していた所、
この記事に行きあたり、Houndというものを見つけた。

上記記事ではselenium-server経由でスクレイピングを行っているが、
特に複数ブラウザで検証したり、ブラウザを立ち上げる必要もないので、
DriverはPhantomJS2を利用する事にする。

まず準備

PhantomJSをインストール

Homebrewではエラーが出たので今回はnpmを使ってインストール

$ brew install phantomjs
phantomjs: OS X Yosemite or older is required.
Error: An unsatisfied requirement failed this build.
# エラーで失敗したのでHomebrewは断念
$ npm install phantomjs

Elixir/mix

mixでプロジェクトを作成して使用するライブラリをプロジェクトの設定ファイルに記述する。

$ mix new scr
mix.exs
...(省略)
def application do
[applications: [:logger, :httpoison, :hound]]
end
defp deps do
[
{:httpoison, "~> 0.7.4"},
{:floki, "~> 0.6"},
{:hound, "~> 0.7.2"}
]
end
...(省略)

続いてmix deps.getを実行して、プロジェクトに必要なライブラリをインストールする。

最後にconfig/config.exsにhoundの設定を記述する。
参考: [GitHub] hound/config

config/config.exs
config :hound, driver: "phantomjs", host: "http://localhost", port: 5555

これでひとまず準備は終わり。

コードを書く

では準備が出来たので、Houndで自分のサイトにアクセスして、サイトのタイトルを取得するプログラムを書いてみる。

lib/scr.ex
defmodule Scr do
use Hound.Helpers
def start do
blog_url = "http://core.garbage-collection.net/"
IO.puts "access to #{blog_url} ..."
Hound.start_session
navigate_to(url)
IO.puts page_title() # => "core dump"というページタイトルが表示されるはず
end
end

いざ実行

まずPhantomJSを立ち上げる

$ phantomjs --webdriver=5555

続いてmixで書いたコードを実行する

$ mix run -e Scr.start
Compiled lib/scr.ex
Generated scr app
access to http://core.garbage-collection.net/ ...
core dump # ちゃんとサイトのタイトルが表示された!

フォームの操作

次にサイトにログインをして、ログイン後のページ内の情報を取得してみる。
今回はHealthPlanet3で試す。

lib/scr.ex(HealthPlanet版)
defmodule Scr do
use Hound.Helpers
def start do
hp_url = "https://www.healthplanet.jp/login.do" # HealthPlanetのURL
user = "ユーザ名"
passwd = "パスワード"
IO.puts "access to #{hp_url} ..."
Hound.start_session
navigate_to(hp_url)
find_element(:name, "loginId") |> fill_field(user)
find_element(:name, "passwd") |> fill_field(passwd)
find_element(:class, "btn_yes") |> submit_element
IO.puts page_title() # => "HealthPlanet ヘルスプラネット"
IO.puts find_element(:id, "userName") |> visible_text # => "こんにちは、xxxxxさん"
end
end

で実行

$ mix run -e Scr.start
Compiled lib/scr.ex
Generated scr app
access to https://www.healthplanet.jp/login.do ...
Health Planet ヘルスプラネット
こんにちは、xxxxxさん

これでフォーム操作含めたスクレイピングはMechanizeなしでもうまくできそうだ。
今回サンプルで試したHealthPlanetにはサイトに保存されている健康データを
APIで取得できるようになっているので、今度はそっちを試してみようと思う。

今日はここまで。

  1. スクレイピングとかWebサイトのフォーム操作を助けてくれるありがたいライブラリ

  2. 画面表示が無い(headlessというらしい)ブラウザ

  3. タニタが運営している健康管理サービス