私の歴史と今

振り返ると恥ずかしくなるのが私の歴史。だけどそのときは真面目に書いていた訳でね。そんな今の私を書いていく。

Rubyでブラウザ操作を擬似的に実現するHTTPクライアント(2)

会社でwatirというライブラリがあることを知ったが、これはブラウザそのものを動かすものらしいので、iMacrosと同類になる。今回はWebサーバのバックエンド処理として実装したいから、watirは不適切。

ということで、mechanizeのコードを書いていく事にする。

Mechanizeのインストール

C:\Documents and Settings\june>ruby -v
ruby 1.9.2p290 (2011-07-09) [i386-mingw32]

C:\Documents and Settings\june>gem install mechanize
Fetching: net-http-digest_auth-1.2.1.gem (100%)
Fetching: net-http-persistent-2.7.gem (100%)
Fetching: nokogiri-1.5.5-x86-mingw32.gem (100%)
Fetching: ntlm-http-0.1.1.gem (100%)
WARNING: ntlm-http-0.1.1 has an invalid nil value for @cert_chain
Fetching: webrobots-0.0.13.gem (100%)
Fetching: unf_ext-0.0.5-x86-mingw32.gem (100%)
Fetching: unf-0.0.5.gem (100%)
Fetching: domain_name-0.5.4.gem (100%)
Fetching: mechanize-2.5.1.gem (100%)
Successfully installed net-http-digest_auth-1.2.1
Successfully installed net-http-persistent-2.7
Successfully installed nokogiri-1.5.5-x86-mingw32
Successfully installed ntlm-http-0.1.1
Successfully installed webrobots-0.0.13
Successfully installed unf_ext-0.0.5-x86-mingw32
Successfully installed unf-0.0.5
Successfully installed domain_name-0.5.4
Successfully installed mechanize-2.5.1
9 gems installed
Installing ri documentation for net-http-digest_auth-1.2.1...
Installing ri documentation for net-http-persistent-2.7...
Installing ri documentation for nokogiri-1.5.5-x86-mingw32...
unable to convert "\xE3" to UTF-8 in conversion from ASCII-8BIT to UTF-8 to Windows-31J for CHANGELOG.ja.rdoc, skipping
unable to convert "\xE8" to UTF-8 in conversion from ASCII-8BIT to UTF-8 to Windows-31J for CHANGELOG.rdoc, skipping
unable to convert "\xE9" to UTF-8 in conversion from ASCII-8BIT to UTF-8 to Windows-31J for README.ja.rdoc, skipping
unable to convert "\xE2" to UTF-8 in conversion from ASCII-8BIT to UTF-8 to Windows-31J for ext/nokogiri/xml_node_set.c, skipping
Installing ri documentation for ntlm-http-0.1.1...
Installing ri documentation for webrobots-0.0.13...
Installing ri documentation for unf_ext-0.0.5-x86-mingw32...
Installing ri documentation for unf-0.0.5...
Installing ri documentation for domain_name-0.5.4...
Installing ri documentation for mechanize-2.5.1...
unable to convert "\xE3" to UTF-8 in conversion from ASCII-8BIT to UTF-8 to Windows-31J for CHANGELOG.rdoc, skipping
Installing RDoc documentation for net-http-digest_auth-1.2.1...
Installing RDoc documentation for net-http-persistent-2.7...
Installing RDoc documentation for nokogiri-1.5.5-x86-mingw32...
unable to convert "\xE3" to UTF-8 in conversion from ASCII-8BIT to UTF-8 to Windows-31J for CHANGELOG.ja.rdoc, skipping
unable to convert "\xE8" to UTF-8 in conversion from ASCII-8BIT to UTF-8 to Windows-31J for CHANGELOG.rdoc, skipping
unable to convert "\xE9" to UTF-8 in conversion from ASCII-8BIT to UTF-8 to Windows-31J for README.ja.rdoc, skipping
unable to convert "\xE2" to UTF-8 in conversion from ASCII-8BIT to UTF-8 to Windows-31J for ext/nokogiri/xml_node_set.c, skipping
Installing RDoc documentation for ntlm-http-0.1.1...
Installing RDoc documentation for webrobots-0.0.13...
Installing RDoc documentation for unf_ext-0.0.5-x86-mingw32...
Installing RDoc documentation for unf-0.0.5...
Installing RDoc documentation for domain_name-0.5.4...
Installing RDoc documentation for mechanize-2.5.1...
unable to convert "\xE3" to UTF-8 in conversion from ASCII-8BIT to UTF-8 to Windows-31J for CHANGELOG.rdoc, skipping

途中Warningが出ているが気にしない! どんどん進むことを考える。
インストールされたgemは以下のとおり。

  • Successfully installed net-http-digest_auth-1.2.1
  • Successfully installed net-http-persistent-2.7
  • Successfully installed nokogiri-1.5.5-x86-mingw32
  • Successfully installed ntlm-http-0.1.1
  • Successfully installed webrobots-0.0.13
  • Successfully installed unf_ext-0.0.5-x86-mingw32
  • Successfully installed unf-0.0.5
  • Successfully installed domain_name-0.5.4
  • Successfully installed mechanize-2.5.1

昨日調べた通り、nokogiriがインストールされていることがわかる。
では、スゴワザ(笑)にログインするところを実装する。

トップページの表示

まずは、ログイン画面を表示するところから。

require 'mechanize'

# HTTPクライアント作成
client = Mechanize::new
 
# GETリクエスト
client.get('http://www.sugowaza.jp/usrs/login/')
p client.page

標準出力した。

#<Mechanize::Page
 {url #<URI::HTTP:0x1974a20 URL:http://www.sugowaza.jp/usrs/login/>}
 {meta_refresh}
 {title "ログイン|スゴワザ"}
 {iframes}
 {frames}
 {links
  #<Mechanize::Page::Link "スゴワザ TOP" "http://www.sugowaza.jp">
  #<Mechanize::Page::Link "パスワードをお忘れの方はこちら" "/usrs/reminder">
  #<Mechanize::Page::Link "⇒ 新規発行者登録はこちら" "/usrs/add/">
  #<Mechanize::Page::Link "\n" "http://www.sugowaza.jp/">
  #<Mechanize::Page::Link
   "\nこのスペースに広告掲載しませんか?"
   "http://www.sugowaza.jp/pages/ad2">
  #<Mechanize::Page::Link "このページの先頭へ" "#container">
  #<Mechanize::Page::Link
   "スゴワザとは"
   "http://www.sugowaza.jp/pages/about_sugowaza/">
  #<Mechanize::Page::Link "広告出稿" "http://www.sugowaza.jp/pages/ad/">
  #<Mechanize::Page::Link "メルマガ読者増" "http://www.sugowaza.jp/pages/home_usr/">
  #<Mechanize::Page::Link "お問い合わせ" "http://faq.sugowaza.jp/">
  #<Mechanize::Page::Link "\n" "http://www.sugowaza.jp/">
  #<Mechanize::Page::Link "\n" "http://www.sugowaza.jp/usrs/add3/">
  #<Mechanize::Page::Link "\n" "http://www.sugowaza.jp/usrs/login/">
  #<Mechanize::Page::Link "影武者のバナー" "http://www.kage-musha.com/">
  #<Mechanize::Page::Link "アクセスアップ(2314)" "/reports/category_index_all/c0107">
  #<Mechanize::Page::Link "ブログ(1296)" "/reports/category_index_all/c0108">
  #<Mechanize::Page::Link "メルマガ(1476)" "/reports/category_index_all/c0109">
  #<Mechanize::Page::Link "携帯(240)" "/reports/category_index_all/c0110">
  #<Mechanize::Page::Link "情報商材(966)" "/reports/category_index_all/c0111">
  #<Mechanize::Page::Link "アフィリエイト(2382)" "/reports/category_index_all/c0102">
  #<Mechanize::Page::Link
   "ネットビジネスその他(2366)"
   "/reports/category_index_all/c0101">
  #<Mechanize::Page::Link
   "株、投資、不動産等(1824)"
   "/reports/category_index_all/c0103">
  #<Mechanize::Page::Link "ギャンブル(1070)" "/reports/category_index_all/c0104">
  #<Mechanize::Page::Link "会社、お店(230)" "/reports/category_index_all/c0105">
  #<Mechanize::Page::Link "マネー関連その他(1700)" "/reports/category_index_all/c0106">
  #<Mechanize::Page::Link "恋愛テクニック(3655)" "/reports/category_index_all/c0201">
  #<Mechanize::Page::Link
   "セクシャル(一部18禁)(512)"
   "/reports/category_index_all/c0202">
  #<Mechanize::Page::Link "恋愛関連その他(745)" "/reports/category_index_all/c0203">
  #<Mechanize::Page::Link "美容、健康(2190)" "/reports/category_index_all/c0303">
  #<Mechanize::Page::Link "教育(680)" "/reports/category_index_all/c0305">
  #<Mechanize::Page::Link "PC、携帯(555)" "/reports/category_index_all/c0301">
  #<Mechanize::Page::Link "趣味(447)" "/reports/category_index_all/c0302">
  #<Mechanize::Page::Link "その他(778)" "/reports/category_index_all/c0304">
  #<Mechanize::Page::Link
   "ピーアールジャパン株式会社"
   "http://www.sugowaza.jp/pages/aboutus/">
  #<Mechanize::Page::Link "無料レポート配布スゴワザ" "http://www.sugowaza.jp">
  #<Mechanize::Page::Link "プライバシーポリシー" "http://www.prjapan.co.jp/privacy.html">
  #<Mechanize::Page::Link "推奨環境" "/pages/aboutenv/">
  #<Mechanize::Page::Link "要望受付、お問い合わせ" "http://faq.sugowaza.jp/">
  #<Mechanize::Page::Link "よくあるご質問" "http://faq.sugowaza.jp/">
  #<Mechanize::Page::Link "メール配信 ステップメール NEO" "http://www.mail-neo.com/">
  #<Mechanize::Page::Link
   "無料(フリー)メールフォーム"
   "https://www.form-answer.com/freeform.html">
  #<Mechanize::Page::Link "問い合わせフォーム作成" "https://www.form-answer.com/">
  #<Mechanize::Page::Link "アマゾンキャンペーン支援" "http://www.amazon-campaign.com/">
  #<Mechanize::Page::Link "QRコード作成" "http://www.qr-code.jp/">
  #<Mechanize::Page::Link "一括投稿" "http://www.prjapan.jp/">
  #<Mechanize::Page::Link "メルマガ読者相互紹介" "http://www.dokusha-barter.com/">
  #<Mechanize::Page::Link
   "WordPress(ワードプレス)サイト作成"
   "http://www.wordpress-shop.com/">
  #<Mechanize::Page::Link "恋愛サイトランキング" "http://ranking.lovewaza.jp/">
  #<Mechanize::Page::Link "スーパーIDスゴワザ!" "http://sid.sugowaza.jp/">}
 {forms
  #<Mechanize::Form
   {name nil}
   {method "POST"}
   {action "/usrs/login/"}
   {fields
    [hidden:0xbca978 type: hidden name: data[_Token][key] value: 0277077e5bd9668e1403b69f8f2a04b98130c309]
    [text:0xbca858 type: text name: data[Usr][username] value: ]
    [field:0xbca720 type: password name: data[Usr][password] value: ]}
   {radiobuttons}
   {checkboxes}
   {file_uploads}
   {buttons [submit:0xbca630 type: submit name:  value: ログイン]}>
  #<Mechanize::Form
   {name nil}
   {method "POST"}
   {action "/reports/search_for_usr/"}
   {fields
    [hidden:0xbc8968 type: hidden name: data[_Token][key] value: 0277077e5bd9668e1403b69f8f2a04b98130c309]
    [text:0xbc8848 type: text name: data[Search][val] value: ]
    [selectlist:0xbc82f0 type:  name: data[Search][category_key] value: []]}
   {radiobuttons}
   {checkboxes}
   {file_uploads}
   {buttons [submit:0xbc8734 type: submit name:  value: レポート検索]}>}>

なるほど。テキストではなく、Mechanize::Pageオブジェクトを取得できるんだね。
注目はこの部分。

  #<Mechanize::Form
   {name nil}
   {method "POST"}
   {action "/usrs/login/"}
   {fields
    [hidden:0xbca978 type: hidden name: data[_Token][key] value: 0277077e5bd9668e1403b69f8f2a04b98130c309]
    [text:0xbca858 type: text name: data[Usr][username] value: ]
    [field:0xbca720 type: password name: data[Usr][password] value: ]}
   {radiobuttons}
   {checkboxes}
   {file_uploads}
   {buttons [submit:0xbca630 type: submit name:  value: ログイン]}>

fieldsとして、以下の3つがある。

  • data[_Token][key]
  • data[Usr][username]
  • data[Usr][password]

tokenが隠しフィールドに設定されているので、アカウント情報に加えてこのトークンもPOSTしないとログインできないってことだね。でもMechanizeならトークンは意識しなくてもいいはず(だよね?)。

実際のHTMLは以下のようになっている。(整形してます)

<form action="/usrs/login/" method="post">
    <input type="hidden" name="data[_Token][key]"  value="ee81dbc4a58b7252f1a881ce5a5c7702515fe1c4" id="_TokenKey" />
    <table border="0" cellpadding="0" cellspacing="0" width="100%" style="border:1px solid #FFFFFF;">
        <tr>
            <td valign=top align=left>
                発行者会員、および、読者会員のためのログインページです。<br />
                登録時のユーザーID、パスワードを利用してログインをお願いします。<br />
                <br />
                <font color="#ff0000">*</font>ユーザーID<br /><span class="annotation">ログインに利用するあなたのIDです。必ず英字を入れてください。半角英数字40字まで</span><br />
                <input name="data[Usr][username]"  class="input" style="width:200px;" id="UsrUsername" value="" type="text" />  <br />

                <font color="#ff0000">*</font>パスワード<br /><span class="annotation">半角英数字20字まで。</span><br />
                <input type="password" name="data[Usr][password]"  class="input" style="width:200px;" id="UsrPassword" value="" />	<br />

                <input type="submit" class="comment-button" value="ログイン" />	<br />
                <br /><a href="/usrs/reminder"  title="パスワードをお忘れの方はこちら">パスワードをお忘れの方はこちら</a>
                <br />
                <br />

                <a href="/usrs/add/"  title="新規発行者登録はこちら">⇒ 新規発行者登録はこちら</a>
</form>
            </td>

あれ。formの閉じ位置がおかしいぞ・・・。まあいいか。。

どう対応しているかというと

    [hidden:0xbca978 type: hidden name: data[_Token][key] value: 0277077e5bd9668e1403b69f8f2a04b98130c309]

は、以下に対応している。

    <input type="hidden" name="data[_Token][key]"  value="ee81dbc4a58b7252f1a881ce5a5c7702515fe1c4" id="_TokenKey" />

valueが異なるのは、htmlソースをブラウザで取得したから。セッションが異なる。

ログイン

では、formの中のボタンを押してみよう。

require 'mechanize'

# HTTPクライアント作成
client = Mechanize::new
 
# GETリクエスト
client.get('http://www.sugowaza.jp/usrs/login/')

# name="login"というフォームの中で、emailとパスワードを入力してPOSTリクエスト
client.page.form_with(:action => '/usrs/login/'){|form|
  form.field_with(:name => 'data[Usr][username]').value = 'user_id'
  form.field_with(:name => 'data[Usr][password]').value = 'password'
  form.click_button
}

p client.page

以下、標準出力の先頭部分。

#<Mechanize::Page
 {url #<URI::HTTP:0x1781b08 URL:http://www.sugowaza.jp/newinfos/>}
 {meta_refresh}
 {title "全体お知らせ管理|スゴワザ"}
 {iframes}
 {frames}
 {links
  #<Mechanize::Page::Link "スゴワザ TOP" "http://www.sugowaza.jp">
  #<Mechanize::Page::Link "「VPS-NEO」アフィリエイトを開始します!" "/newinfos/view/112">
  #<Mechanize::Page::Link "登録はコチラ!" "http://www.neo-vps.com/usrs/add/">
  #<Mechanize::Page::Link "登録はコチラ!" "http://www.neo-vps.com/usrs/add/">
  #<Mechanize::Page::Link "このページの先頭へ" "#container">
  #<Mechanize::Page::Link
   "スゴワザとは"
   "http://www.sugowaza.jp/pages/about_sugowaza/">
  #<Mechanize::Page::Link "広告出稿" "http://www.sugowaza.jp/pages/ad/">
  #<Mechanize::Page::Link "メルマガ読者増" "http://www.sugowaza.jp/pages/home_usr/">
  #<Mechanize::Page::Link "お問い合わせ" "http://faq.sugowaza.jp/">
  #<Mechanize::Page::Link "\n" "http://www.sugowaza.jp/">
  #<Mechanize::Page::Link "発行者管理画面" "http://www.sugowaza.jp/usrs/r_index">
  #<Mechanize::Page::Link "ログアウト" "http://www.sugowaza.jp/usrs/logout/">
  #<Mechanize::Page::Link "登録情報の修正" "/usrs/edit/">
  #<Mechanize::Page::Link "退会" "/usrs/quit/">
  #<Mechanize::Page::Link "影武者のバナー" "http://www.kage-musha.com/">
  #<Mechanize::Page::Link "アクセスアップ(2314)" "/reports/category_index_all/c0107">
  #<Mechanize::Page::Link "ブログ(1296)" "/reports/category_index_all/c0108">
  #<Mechanize::Page::Link "メルマガ(1476)" "/reports/category_index_all/c0109">
  #<Mechanize::Page::Link "携帯(240)" "/reports/category_index_all/c0110">
  #<Mechanize::Page::Link "情報商材(966)" "/reports/category_index_all/c0111">
  #<Mechanize::Page::Link "アフィリエイト(2382)" "/reports/category_index_all/c0102">
  #<Mechanize::Page::Link
   "ネットビジネスその他(2366)"
   "/reports/category_index_all/c0101">
  #<Mechanize::Page::Link
   "株、投資、不動産等(1824)"
   "/reports/category_index_all/c0103">
  #<Mechanize::Page::Link "ギャンブル(1070)" "/reports/category_index_all/c0104">
  #<Mechanize::Page::Link "会社、お店(230)" "/reports/category_index_all/c0105">
  #<Mechanize::Page::Link "マネー関連その他(1700)" "/reports/category_index_all/c0106">
  #<Mechanize::Page::Link "恋愛テクニック(3655)" "/reports/category_index_all/c0201">
  #<Mechanize::Page::Link
   "セクシャル(一部18禁)(512)"
   "/reports/category_index_all/c0202">
  #<Mechanize::Page::Link "恋愛関連その他(745)" "/reports/category_index_all/c0203">
  #<Mechanize::Page::Link "美容、健康(2190)" "/reports/category_index_all/c0303">
  #<Mechanize::Page::Link "教育(680)" "/reports/category_index_all/c0305">
  #<Mechanize::Page::Link "PC、携帯(555)" "/reports/category_index_all/c0301">
  #<Mechanize::Page::Link "趣味(447)" "/reports/category_index_all/c0302">
  #<Mechanize::Page::Link "その他(778)" "/reports/category_index_all/c0304">
  #<Mechanize::Page::Link
   "ピーアールジャパン株式会社"
   "http://www.sugowaza.jp/pages/aboutus/">
  #<Mechanize::Page::Link "無料レポート配布スゴワザ" "http://www.sugowaza.jp">
  #<Mechanize::Page::Link "プライバシーポリシー" "http://www.prjapan.co.jp/privacy.html">
  #<Mechanize::Page::Link "推奨環境" "/pages/aboutenv/">
  #<Mechanize::Page::Link "要望受付、お問い合わせ" "http://faq.sugowaza.jp/">
  #<Mechanize::Page::Link "よくあるご質問" "http://faq.sugowaza.jp/">
  #<Mechanize::Page::Link "メール配信 ステップメール NEO" "http://www.mail-neo.com/">
  #<Mechanize::Page::Link
   "無料(フリー)メールフォーム"
   "https://www.form-answer.com/freeform.html">
  #<Mechanize::Page::Link "問い合わせフォーム作成" "https://www.form-answer.com/">
  #<Mechanize::Page::Link "アマゾンキャンペーン支援" "http://www.amazon-campaign.com/">
  #<Mechanize::Page::Link "QRコード作成" "http://www.qr-code.jp/">
  #<Mechanize::Page::Link "一括投稿" "http://www.prjapan.jp/">
  #<Mechanize::Page::Link "メルマガ読者相互紹介" "http://www.dokusha-barter.com/">
  #<Mechanize::Page::Link
   "WordPress(ワードプレス)サイト作成"
   "http://www.wordpress-shop.com/">
  #<Mechanize::Page::Link "恋愛サイトランキング" "http://ranking.lovewaza.jp/">
  #<Mechanize::Page::Link "スーパーIDスゴワザ!" "http://sid.sugowaza.jp/">}
 {forms
  #<Mechanize::Form
   {name nil}
   {method "POST"}
   {action "/newinfos/"}
   {fields
    [hidden:0xba0948 type: hidden name: data[_Token][key] value: db1b4876ff0b0d1be17791a28de1a028842f06eb]
    [hidden:0xba081c type: hidden name: check value: 1]
    [hidden:0xba06fc type: hidden name: last_id value: 112]}
   {radiobuttons}
   {checkboxes}
   {file_uploads}
   {buttons [submit:0xba05b8 type: submit name:  value: 確認しました]}>
  #<Mechanize::Form
   {name nil}
   {method "POST"}
   {action "/reports/search_for_usr/"}
   {fields
    [hidden:0xb9f934 type: hidden name: data[_Token][key] value: db1b4876ff0b0d1be17791a28de1a028842f06eb]
    [text:0xb9f820 type: text name: data[Search][val] value: ]
    [selectlist:0xb9f298 type:  name: data[Search][category_key] value: []]}
   {radiobuttons}
   {checkboxes}
   {file_uploads}
   {buttons [submit:0xb9f718 type: submit name:  value: レポート検索]}>}>

URLがログイン後になっているのがわかる。
で、この画面はどんな画面かというと、お知らせ画面。お知らせがあるときだけ表示される。必ず表示される訳ではないのがいやらしいところ。でも、Rubyで処理できるからそんなの簡単。

重要なお知らせ画面の次へ

この画面の最後に「確認しました」というボタンがあるので、それを押すことにする。

require 'mechanize'

# HTTPクライアント作成
client = Mechanize::new
 
# GETリクエスト
client.get('http://www.sugowaza.jp/usrs/login/')

# ログイン(name="login"というフォームの中で、emailとパスワードを入力してPOSTリクエスト)
client.page.form_with(:action => '/usrs/login/'){|form|
  form.field_with(:name => 'data[Usr][username]').value = 'user_id'
  form.field_with(:name => 'data[Usr][password]').value = 'password'
  form.click_button
}

# 「重要なお知らせ」があれば更に次へ進む(複数回表示される可能性があるのでループ)
while client.page.form_with(:action => '/newinfos/') != nil
  p "重要なお知らせ画面表示"
  client.page.form_with(:action => '/newinfos/'){|form|
    form.click_button
  }
end

p client.page

以下の標準出力。

"重要なお知らせ画面表示"
#<Mechanize::Page
 {url #<URI::HTTP:0x16dc448 URL:http://www.sugowaza.jp/>}
 {meta_refresh}
 {title "無料レポートと電子書籍の無料ダウンロード|スゴワザ"}
 {iframes}
 {frames}
 {links
  #<Mechanize::Page::Link "発行者管理画面" "http://www.sugowaza.jp/usrs/r_index">
(ありすぎるのでリンクは省略)
 {forms
  #<Mechanize::Form
   {name nil}
   {method "POST"}
   {action "http://lods.sakura.ne.jp/neo/usrctrl.php"}
   {fields
    [hidden:0xae5e38 type: hidden name: mag_id value: 76]
    [hidden:0xae5d24 type: hidden name: type value: form]
    [hidden:0xae5c10 type: hidden name: charset value: u]
    [hidden:0xae5af0 type: hidden name: act value: add]
    [text:0xae5a0c type: text name: email value: ]
    [text:0xae5880 type: text name: name value: ]}
   {radiobuttons}
   {checkboxes}
   {file_uploads}
   {buttons [submit:0xae56c4 type: submit name:  value:  購読する ]}>
  #<Mechanize::Form
   {name nil}
   {method "POST"}
   {action "/reports/search_for_usr/"}
   {fields
    [hidden:0xadf5c8 type: hidden name: data[_Token][key] value: 3936923d2f737f04957ca65b3c8eb6e3fcd31867]
    [text:0xadf34c type: text name: data[Search][val] value: ]
    [selectlist:0xade8d8 type:  name: data[Search][category_key] value: []]}
   {radiobuttons}
   {checkboxes}
   {file_uploads}
   {buttons [submit:0xadf1b4 type: submit name:  value: レポート検索]}>}>

リンクとして「発行者管理画面」というものがあるのがわかる。

発行者管理画面へ移動

次はリンクをクリックしてみよう。

以下、標準出力。

"重要なお知らせ画面表示"
#<Mechanize::Page
 {url #<URI::HTTP:0x1565460 URL:http://www.sugowaza.jp/usrs/r_index>}
 {meta_refresh}
 {title "無料レポートユーザ用トップページ|スゴワザ"}
 {iframes}
 {frames}
 {links
  #<Mechanize::Page::Link "スゴワザ TOP" "http://www.sugowaza.jp">
  #<Mechanize::Page::Link "獲得した読者のダウンロード" "/emails/">
  #<Mechanize::Page::Link "無料レポートの紹介" "#2">
  #<Mechanize::Page::Link "無料レポートをお持ちの方" "#3">
(ありすぎるのでリンクは省略)
 {forms
  #<Mechanize::Form
   {name nil}
   {method "POST"}
   {action "/reports/search_for_usr/"}
   {fields
    [hidden:0x9abd14 type: hidden name: data[_Token][key] value: 4d74e8f6bba5f7b9f0cbd6a03449d2de7dee3879]
    [text:0x9abba0 type: text name: data[Search][val] value: ]
    [selectlist:0x9ab594 type:  name: data[Search][category_key] value: []]}
   {radiobuttons}
   {checkboxes}
   {file_uploads}
   {buttons [submit:0x9aba14 type: submit name:  value: レポート検索]}>}>

「獲得した読者のダウンロード」というリンクがあるのがわかる。実は、ログイン後、無料レポートをダウンロードしてくれた人のメールアドレスをダウンロードしたい。

ダウンロードページへ

require 'mechanize'

# HTTPクライアント作成
client = Mechanize::new
 
# GETリクエスト
client.get('http://www.sugowaza.jp/usrs/login/')

# ログイン(name="login"というフォームの中で、emailとパスワードを入力してPOSTリクエスト)
client.page.form_with(:action => '/usrs/login/'){|form|
  form.field_with(:name => 'data[Usr][password]').value = 'password'
  form.click_button
}

# 「重要なお知らせ」があれば更に次へ進む(複数回表示される可能性があるのでループ)
while client.page.form_with(:action => '/newinfos/') != nil
  p "重要なお知らせ画面表示"
  client.page.form_with(:action => '/newinfos/'){|form|
    form.click_button
  }
end

# 「発行者管理画面」というリンクをクリック
client.page.link_with(:text => '発行者管理画面').click

# 「獲得した読者のダウンロード」というリンクをクリック
client.page.link_with(:href => '/emails/').click

p client.page

「獲得した読者のダウンロード」というアンカーテキストが長すぎて変更になる可能性があるので、クリックの特定はhref属性ですることにした。他のリンクも含め、hrefでするのが無難だな。

以下、リンクを押した後の標準出力。ダウンロードするリンクがあるのがわかる。

"重要なお知らせ画面表示"
#<Mechanize::Page
 {url #<URI::HTTP:0x1414f80 URL:http://www.sugowaza.jp/emails/>}
 {meta_refresh}
 {title "ダウンロードページ|スゴワザ"}
 {iframes}
 {frames}
 {links
  #<Mechanize::Page::Link "スゴワザ TOP" "http://www.sugowaza.jp">
  #<Mechanize::Page::Link
   "\n特定電子メールの送信等に関するガイドライン(総務省ページ)"
   "http://www.soumu.go.jp/main_sosiki/joho_tsusin/d_syohi/pdf/m_mail_081114_1.pdf">
  #<Mechanize::Page::Link
   "http://www2.sugowaza.jp/reports/getu/1/906/0000185795"
   "http://www2.sugowaza.jp/reports/getu/1/906/0000185795">
  #<Mechanize::Page::Link "一括ダウンロード" "/emails/downloadall/">
  #<Mechanize::Page::Link
   "PRJAPAN mail 名前付き一括登録形式一括ダウンロード"
   "/emails/downloadall/1">
  #<Mechanize::Page::Link "一括ダウンロード レポート名つき" "/emails/downloadall/2">
  #<Mechanize::Page::Link "一括ダウンロード 応募情報つき" "/emails/downloadall/3">
  #<Mechanize::Page::Link "一括ダウンロード メルアドのみ" "/emails/downloadall/4">
  #<Mechanize::Page::Link "ダウンロード" "/emails/download/2012-10-11">
  #<Mechanize::Page::Link
   "PRJAPAN mail 名前付き一括登録形式ダウンロード"
   "/emails/download/2012-10-11/1/">
  #<Mechanize::Page::Link "ダウンロード レポート名つき" "/emails/download/2012-10-11/2/">
  #<Mechanize::Page::Link "ダウンロード 応募情報つき" "/emails/download/2012-10-11/3/">
  #<Mechanize::Page::Link "ダウンロード メルアドのみ" "/emails/download/2012-10-11/4/">
  #<Mechanize::Page::Link "ダウンロード" "/emails/download/2012-10-09">
  #<Mechanize::Page::Link
   "PRJAPAN mail 名前付き一括登録形式ダウンロード"
   "/emails/download/2012-10-09/1/">
  #<Mechanize::Page::Link "ダウンロード レポート名つき" "/emails/download/2012-10-09/2/">
  #<Mechanize::Page::Link "ダウンロード 応募情報つき" "/emails/download/2012-10-09/3/">
  #<Mechanize::Page::Link "ダウンロード メルアドのみ" "/emails/download/2012-10-09/4/">
  #<Mechanize::Page::Link "" "http://www.sugowaza.jp/suponsors/add">
  #<Mechanize::Page::Link "詳細・申込はこちら" "http://www.sugowaza.jp/suponsors/add">
  #<Mechanize::Page::Link "このページの先頭へ" "#container">
(ありすぎるのでリンクは省略)
 {forms
  #<Mechanize::Form
   {name nil}
   {method "POST"}
   {action "/reports/search_for_usr/"}
   {fields
    [hidden:0x94bbe8 type: hidden name: data[_Token][key] value: 4879c33f52c6ffc378800b40efd2c7f67108e729]
    [text:0x94bb04 type: text name: data[Search][val] value: ]
    [selectlist:0x94a5d4 type:  name: data[Search][category_key] value: []]}
   {radiobuttons}
   {checkboxes}
   {file_uploads}
   {buttons [submit:0x94ba08 type: submit name:  value: レポート検索]}>}>

うう。。。眠い。。。明日は朝早くから敦賀出張だから、寝る。。。