04/28ちょこっと追記と数カ所修正しました。
What’s that?
Capybaraはウェブシステムのテストを補助するRubyのライブラリです。
Mechanizeでほとんどのサイトはクロールできますが、JavaScriptなサイトに対してはJavaScriptが解釈できるようなものでクロールしないといけません。
とくに真新しい単語が入っている訳でもなく、これを読んだだけだと別に何もピンと来たりはしないかもしれない。
GUI環境なのかCUI環境なのかという問題は、それと同じくらい普段は意識しないことだと思いますが、何も明記していない場合はGUI環境なんだよ〜というのは、もしかすると初めてだったかもしれないくらい。
今回はわりと大きな問題だったようです。
インストール
参考サイト
github.com/thoughtbot/capybara-webkit
CapybaraとCapybara-webkitというものをインストールします。
Gemでインストール可能ですが、Capybara-webkitのインストールにはQT(キュート)というものが必要なようで、まずはそこから。
Capybara-webkitはCapybaraが利用するドライバーのうちの1つで、他にもRackTest、Poltergeist、Selenium などがあります。
参考書籍だとPoltergeist+PhantomJSが人気らしく、書籍の中でもこの組み合わせでの説明になってます。ウェブの情報もそれなりに多いCapybara-webkitで進めてみたいと思います。
その辺りは置き換えて読んでいく必要がありますが、まぁ何とかなります。
では、参考サイトとCapybara-webkitのインストールに戻りませう。
ザーッとマニュアルと読んでみると、その時に使っていたOSがCentos6だったのでRHELのところが目についた。
ってことで
sudo yum search qtwebkit-devel 警告: 一致するものが見つかりません: qt-webkit-devel 見つかりませんでした sudo yum search qtwebkit-devel qtwebkit-devel.x86_64 : Development files for qtwebkit
という感じに、あまり深く考えずにRHEL16のところで進めていくと。
sudo yum install qtwebkit-devel tail -2 ~/.zshrc [~/ruby] export EDITOR=/usr/bin/vim exec $SHELL -l qmake-qt4 -v [~/ruby] QMake version 2.01a Using Qt version 4.6.2 in /usr/lib64
っつーか、これだとダメみたい。
Capybara-webkitのインストールは失敗しました。
と出ます。
この件から得る教訓は、急がば回れということらしい。
気を取り直してCent6の手順でインストール
RHELのところから下に下がって良く見てみるとCentos6の手順がちゃんと書いてありました。
この辺は参考サイトと同じです。
sudo yum install libxcb libxcb-devel xcb-util xcb-util-devel sudo yum install flex bison gperf libicu-devel libxslt-devel ruby sudo yum install libXrender-devel cd ~/tmp wget http://download.qt-project.org/official_releases/qt/4.8/4.8.6/qt-everywhere-opensource-src-4.8.6.tar.gz cd qt-everywhere-opensource-src-4.8.6
選択肢の部分は参考サイトから少し変わった様子?
さきほどの教訓がぜんぜん活かされていない気がしますが、Yesを選択してみました。
./configure -opensource -nomake examples -nomake tests This is the Open Source Edition. You are licensed to use this software under the terms of the Lesser GNU General Public License (LGPL) versions 2.1. You are also licensed to use this software under the terms of the GNU General Public License (GPL) versions 3. Do you accept the terms of either license? yes
しばらく待っていると以下のメッセージが表示されました。どうやら残りは普通に同じように進められそうですね。
Qt is now configured for building. Just run 'gmake'. Once everything is built, you must run 'gmake install'. Qt will be installed into /usr/local/Trolltech/Qt-4.8.6 To reconfigure, run 'gmake confclean' and 'configure'.
あとはgmakeでフィニッシュ。
なんですが、Gmakeがめちゃ長いので時間がない時は避けておくのをオススメ。
sudo gmake sudo gmake install sudo ln -s /usr/local/Trolltech/Qt-4.8.6/bin/qmake /usr/bin/qmake gem install capybara-webkit [/tmp/qt-everywhere-opensource-src-4.8.6] Building native extensions. This could take a while... Successfully installed capybara-webkit-1.5.1 1 gem installed
できた〜!と思ったら?
簡単なテストスクリプトを実行してみると
Capybara::Webkit::ConnectionError
ここでようやく参考にしていたサイト全てがGUI環境を前提にしていたことに気づいた。
・・・なんということでしょう。
CUIの場合はHeadlessとXvfbが必要ということらしい。
本来?という言い方はおかしいですが、本来はウェブサイトのテストに使ってたものらしいので、GUIを前提としていてもおかしくないのかなぁと振り返ってみるとそう思ったりして。
$ gem install headless [~/ruby/Capybara_test] Fetching: headless-2.0.0.gem (100%) Successfully installed headless-2.0.0 1 gem installed
エラー内容が変わる。
どうにもこうにもX環境がない場合は、Xvfbとやらを使えということらしい。
Xvfb not found on your system (Headless::Exception) yum search Xvfb ======================================== N/S Matched: Xvfb ======================================== xorg-x11-server-Xvfb.x86_64 : A X Windows System virtual framebuffer X server.
Headlessという単語は以前にも見覚えがあり
Vagrant+VirtualBoxとpackerで検証環境を作ろう
VirtualBoxのテストでCUIだけで操作したいときはHeadless=Trueというオプションを使っていました。そんな感じということですね。
ではスクリプトを使ってテストしてみます
#!/usr/bin/env ruby # coding: utf-8 require 'capybara' require 'capybara-webkit' require 'uri' require 'nokogiri' require 'headless' headless = Headless.new headless.start Capybara.javascript_driver = :webkit client = Capybara::Session.new(:webkit) client.visit 'https://www.google.com/' client.save_screenshot 'google.png' headless.destroy
Googleに接続して画面キャプチャを取るだけのスクリプトです。
$ ls google.png [~/ruby/Capybara_test] google.png
無事に動作したようです。
ではサイバーダック君を使って、サーバーとSFTPで繋いでDLしてチェックしてみませう。
04/28追記ここから
今回はこれで終わろうと思いましたが、2回に分けようと思っていた事がそれほど大きくなさげなので一緒にしてしまいます。
DSLタイプとインスタンスメソッドタイプ
使えるメソッドは同じなようで少し違っているみたいですが、細かいとこは置いておいて視覚的にはDSLの方が綺麗かな?
参考書籍のAmazonのサンプルを参考にしてCapybara-webkitの場合で、DSLを使ったタイプとインスタンスメソッドを使った2タイプで書いてみました。
最初に両方やってみてDSLの方が良さそうなのでこの後はずっとDSLで進めています。書籍もDSLですしね。こちらはCapybara-webkitで進めているとこもそれほど気にならないで進めれています。
インスタンスメソッドを使ったケース
require 'capybara' require 'capybara-webkit' require 'headless' headless = Headless.new headless.start # スクリプトの終わりを告げるhoge END { headless.destroy ; p "hoge" } module Crawler class Amazon def initialize Capybara.javascript_driver = :webkit @client = Capybara::Session.new(:webkit) @client.visit 'https://affiliate.amazon.co.jp/' @client.fill_in :username, with: 'YourAccountName' @client.fill_in :password, with: 'YourPassword' @client.click_button 'サインイン' end def portal @client.select('昨日', :from => 'preSelectedPeriod') @client.first('.line-item-links').click_link("レポート全体を表示") @client.within(:xpath, "//*[@class='totals']") do puts "発送すみ:"+@client.all('td')[1].text end end end end
DSLを使ったケース
require 'capybara' require 'capybara/dsl' require 'capybara-webkit' require 'headless' headless = Headless.new headless.start # スクリプトの終わりを告げるhoge END { headless.destroy ; p "hoge" } module Crawler class Amazon include Capybara::DSL Capybara.javascript_driver = :webkit Capybara.current_driver = :webkit Capybara.app_host = "https://affiliate.amazon.co.jp/" def initialize visit '' fill_in :username, with: 'YourAccountname' fill_in :password, with: 'YourPassword' click_button 'サインイン' end def portal select('昨日', :from => 'preSelectedPeriod') first('.line-item-links').click_link("レポート全体を表示") within(:xpath, "//*[@class='totals']") do puts "発送すみ:"+all('td')[1].text end end end end
Xpathなんかも使ってスクレイピングできるようなので、Mechanizeで蓄えていたことも使えそうですね。
全く関係ない話ですが
今回からKobitoを使って下書きしてマークダウン式にしてみました。
参考書籍
Rubyによるクローラー開発技法
佐々木拓郎 るびきち 著
ソフトバンククリエイティブ