こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

RubyによるMechanizeを利用したformの取得について

kamuycikapです。

<環境>
OS : Windows7
Ruby: ActiveScriptRuby
    ruby 1.8.7 (2009-06-12 patchlevel 174) [i386-mswin32]

<やりたいこと>
手順1.ログインページにアクセスし、ログインIDとパスワードを入力し、ログインボタンをクリックする。
手順2.手順1から遷移したページに設置されている「CSVダウンロード」ボタンをクリックしてCSVファイルを取得する

<ソースコード>
---ここから
require 'rubygems'
require 'mechanize'
require 'kconv'

agent = WWW::Mechanize.new
page = agent.get('https://www.superdelivery.com/common/auth/login')
login_form = page.forms.first
login_form.fields[0].value = "hogehoge"  # ログインID入力
login_form.fields[1].value = "foobar"   # パスワード入力
redirect_page = agent.submit(login_form)

---ここまで

上記プログラムを実行すると下記のエラーが発生します。
undefined method `fields' for nil:NilClass (NoMethodError)

pメソッドを利用してpageを画面に表示してみた処、以下の様子です。
---ここから
#<WWW::Mechanize::Page
{url
#<URI::HTTPS:0x467dba4 URL:https://www.superdelivery.com/common/auth/login>}
{meta}
{title
"\343\202\242\343\203\221\343\203\254\343\203\253\343\203\273\351\233\221\350\
262\250\343\202\222\345\215\270\350\262\251\345\243\262-\343\202\271\343\203\274
\343\203\221\343\203\274\343\203\207\343\203\252\343\203\220\343\203\252\343\203
\274"}
{iframes}
{frames}
{links
#<WWW::Mechanize::Page::Link "" nil>
#<WWW::Mechanize::Page::Link
"\347\271\247\357\275\271\347\271\235\357\275\274\347\271\235\344\273\243"
"http://www.superdelivery.com/">}
{forms}>
---ここまで

どうも、formを引っ張ってこれてない模様です。
name属性が設定されていれば問題無いのかもしれないのですが、name属性もありません。
結果として、ログインを行うことすら出来ておりません。
formの内部にあるテキスト領域等にアクセスするためのメソッドはformクラスのFieldにぶら下がっている様子ですので、formが取得できてなければ利用できないのではないかと想像しています。

参考にしたサイトは下記のとおりです。
http://mechanize.rubyforge.org/mechanize/WWW/Mechanize/Form/MultiSelectList.html
http://d.hatena.ne.jp/kitamomonga/20090307/ruby_mwchanize_0_9_2_out

WIN32OLEを使って、IEを自動操縦する事も検討したのですが、出来るならMechanizeを利用してスマートに処理を実行したいです。

上記のコードは私が利用しているサイトのログインページですが、ログインを利用するページでname属性の無いformを利用しているページであれば何処でも一緒なのではないかと思います。
解決策についてご教示願います。

投稿日時 - 2009-12-03 18:07:36

QNo.5495452

すぐに回答ほしいです

質問者が選んだベストアンサー

>{forms}>
formsが空だからですね。

そのサイトを見てみましたが、非道いページですね。
・ページの文字コードはUTF-8
・HTTPヘッダで示される文字コードはUTF-8
・ページ中のMETAタグで示される文字コードはShift_JIS
サイトのユーザなら、先方に教えてあげましょう。

HTTPヘッダの指定より、METAタグの指定が優先されるので、MechanizeはShift_JISだと思ってページを解釈しようとして、失敗します。

ページ解釈前に、ページのMETAタグを書き直す(か削除する)必要があります。

agent = WWW::Mechanize.new
agent.post_connect_hooks << Proc.new do |params|
if %r|text/html| =~ params[:response]["Content-Type"]
params[:response_body] = params[:response_body].sub(/Shift_JIS/,"utf-8")
end
end
page = agent.get('https://www.superdelivery.com/common/auth/login')

hooksへの設定は、agent作成後に一度だけ行えばいいです。ページ取得直後にProcの内容(Shift_JIS => utf-8)が毎回実施されます。

投稿日時 - 2009-12-03 21:25:21

補足

回答ありがとうございます。
プログラムを実行すると

syntax error, unexpected $end

と表示されます。
今現在googleで調査している最中なんですが、これは文字コードの問題でしょうか???

そのあたり詳しくなくて申し訳ないですが、ご存知でしたらご教示願います。

投稿日時 - 2009-12-04 11:15:53

お礼

To : notnotさん

おばかな補足してすみません。
自己解決できました。

そして

{forms
#<WWW::Mechanize::Form
{name nil}
{method "POST"}
{action "https://www.superdelivery.com/common/auth/login/check"}
{fields
#<WWW::Mechanize::Form::Field:0x46704f4 @name="identification", @value="">
#<WWW::Mechanize::Form::Field:0x4670350 @name="password", @value="">}
{radiobuttons}
{checkboxes}
{file_uploads}
{buttons
#<WWW::Mechanize::Form::Button:0x46701d4
@name="submit",
@value="\343\203\255\343\202\260\343\202\244\343\203\263">}>}>

となり、無事にformを取得することが出来ました。
やっと開発が進みます。
回答ありがとうございました。

投稿日時 - 2009-12-04 12:22:16

ANo.1

このQ&Aは役に立ちましたか?

1人が「このQ&Aが役に立った」と投票しています

回答(1)

あなたにオススメの質問