george's ぶろぐ

Rubyでスクレイピング !

Webサイトをスクレイピングしてみました。いろいろと勉強も兼ねてRubyで作ってみました。
UFJ銀行のネットバンキングのWebページにログインして、表示される金額を取得します。

f:id:whippet_818:20170222231147j:plain:w500

環境

CentOS 6.7
ruby 2.3.1

サーバ側でRubyを実行します。処理内でブラウザからログインし、値を取得します。
少し前までは mechanize というので、Webサイトに対して入力や送信を行うのが普通だったみたいなんですが、Javascript が動くサイトではそれを解釈・実行できないので、最近はCapybara というライブラリを使うのが一般的なようです。


準備

PhantomJS

PhantomJS は画面のない、ヘッドレスなブラウザだそうです。GUI の自動テストに使用されたりするようです。

yum でインストールします。
CentOS6にyumでphantomjs 2.1.1をインストール - Qiita ここに書いてあるとおりです。

$ sudo yum install epel-release
$ sudo rpm -ivh http://repo.okay.com.mx/centos/6/x86_64/release/okay-release-1-1.noarch.rpm
$ sudo yum search all phantomjs

Capybara と Poltergeist を入れる

以下をgem ファイルに追記します。

gem 'capybara'
gem 'poltergeist'

追記後bundle install を実行します。
これで準備が整いました。以降はruby でゴリゴリ作っていく工程です。

Webサイトにアクセス~ログイン

  • モジュールの導入
require 'capybara'
require 'capybara/dsl'
require 'capybara/poltergeist'
  • Capybaraの設定
Capybara.configure do |config|
  config.run_server = false
  config.current_driver = :poltergeist
  config.javascript_driver = :poltergeist
  config.app_host = "http://direct.bk.mufg.jp/"
  config.default_wait_time = 5
end

Capybara.register_driver :poltergeist do |app|
  Capybara::Poltergeist::Driver.new(app, {:js_errors => false, :timeout => 1000 })
end
  • Webサイトにアクセス~ログインページに移動
page.driver.headers = { "User-Agent" => "Mac Safari" }
visit('')
find(:xpath, "//*[@class='mt5']/a/img[contains(./@alt, 'ログイン')]").click
switch_to_window { title == 'ログイン - 三菱東京UFJ銀行' }

ログインページのタブへ移動します。ここ結構詰まりました。UFJのサイトの場合、ログインページには直接アクセスできませんでした。ログインボタンを押してから、新しいタブに生成されるページに移動する必要があります。(このページの最初に貼ってあるイメージです)

※参考 -タブの遷移
Method: Capybara::Session#switch_to_window — Documentation for jnicklas/capybara (master)


  • 契約番号とパスワードの入力
keiyaku_input = find(:xpath, "//input[@type='text']")
keiyaku_input.native.send_key('あなたの契約番号')
password_input = find(:xpath, "//input[@type='password']")
password_input.native.send_key('あなたのパスワード')

契約番号 とパスワード を入力します。 基本的にXPath で入力部分を探していますが、以下の場合でもOKでした。  

fill_in "KEIYAKU_NO", :with => 'あなたの契約番号'

fill を使って入力する方法や、

password_input = find('input#ib_password') 
password_input.native.send_key('あなたのパスワード')

find でもいろいろな検索方法が使えるようです。

XPath についてはこちら
xpathまとめ - Qiita


  • ログインボタン押下後、残高部分を出力
find(:xpath, "//p[@class='acenter admb_m']/a/img[contains(./@alt, 'ログイン')]").click
puts find(:xpath, "//td[@class='number']").text

プログラムを実行し、ターミナルに「~~円」と出力されることを確認します。


全体

require 'capybara'
require 'capybara/dsl'
require 'capybara/poltergeist'

Capybara.configure do |config|
  config.run_server = false
  config.current_driver = :poltergeist
  config.javascript_driver = :poltergeist
  config.app_host = "http://direct.bk.mufg.jp/"
  config.default_wait_time = 5
end

Capybara.register_driver :poltergeist do |app|
  Capybara::Poltergeist::Driver.new(app, {:timeout=>120, js_errors: false})
end

module Scraper
  class ScraperUfj
    include Capybara::DSL

    def initialize(userID, password)
      @userID = userID
      @password = password
    end

    def open_loginpages
      page.driver.headers = { "User-Agent" => "Mac Safari" }
      visit('')
      find(:xpath, "//*[@class='mt5']/a/img[contains(./@alt, 'ログイン')]").click
    end

    def balance_get
      switch_to_window { title == 'ログイン - 三菱東京UFJ銀行' }
  
      keiyaku_input = find(:xpath, "//input[@type='text']")
      keiyaku_input.native.send_key(@userID)
      password_input = find(:xpath, "//input[@type='password']")
      password_input.native.send_key(@password)

      # click_link "ログイン"
      find(:xpath, "//p[@class='acenter admb_m']/a/img[contains(./@alt, 'ログイン')]").click
      puts find(:xpath, "//td[@class='number']").text
    end
  end
end

scraper = Scraper::ScraperUfj.new('あなたの契約番号', 'あなたのパスワード')
scraper.open_loginpages
scraper.balance_get

感想とか

途中何度か詰まりながらも試行錯誤しながら、なんとか動きました。今回ゼロベースの知識からはじめましたが、知らない技術を身につける過程はトキメキます。スクレイピング面白いよ!