Hatena::ブログ(Diary)

bonlife このページをアンテナに追加 RSSフィード

言及ISBN/ASIN
  • Ringo EXPO 08 [DVD]
  • 三文ゴシップ
  • my way
  • ビジネスパーソンのための話し方入門 (日経文庫)
  • ザ・グーグルウェイ グーグルを成功へ導いた型破りな戦略
  • 考え・書き・話す3つの魔法
  • 自分の答えのつくりかた―INDEPENDENT MIND

2007-07-24 夏はライヴの季節です。

mechanizeを使ってreadonlyのフィールドに無理やり値をセットするサンプル

久しぶりに MEET THE WORLD BEAT に行かなかったbonlifeです。ライヴジャンキー失格です。MINAMI WHEEL 2007には行きます。

さてさて、会社ログインをmechanizeで自動化して、あれこれしようと思っていたところ、hidden になってるフィールドへの値の設定で躓いてしまったので、その時のメモです。

まず、以下のようにしてログインを試みました。

In [1]: import mechanize

In [2]: br = mechanize.Browser()

In [3]: br.set_proxies({})

In [4]: br.addheaders = [('User-agent', 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)')]

In [5]: br.open('https://www.example.com/login')
Out[5]: <response_seek_wrapper at 0x12b79b8 (0) whose wrapped object = <closeable_response at 0x12b7800 whose fp = <socket._fileobject object at 0x0122DF10>>>

In [6]: br.select_form(nr=0)

In [7]: br['username'] = 'foo'
---------------------------------------------------------------------------
<type 'exceptions.ValueError'>            Traceback (most recent call last)

C:\...\<ipython console> in <module>()

C:\...\build\bdist.win32\egg\ClientForm.py in __setitem__(self, name, value)

<type 'exceptions.ValueError'>: control 'username' is readonly

proxy設定がらみの対処法については「sh1.2 pyblosxom : mechanizeを使ってみる」を参考にしました。JavaScriptを使ってクライアントサイドでUser-agentをチェックしている画面なので、addheaders でIE6の気分になりまして。で、select_formして、usernameをセット…と思ったら、ナニコレ、readonlyって!

formは実際のところどうなってんのよ、と思ってチェック。

In [8]: print br.form
<POST https://www.example.com/login application/x-www-form-urlencoded
  <HiddenControl(username=) (readonly)>
  <HiddenControl(password=) (readonly)>>

readonly…。HTML上で <input type="hidden"> になってるフィールドはreadonlyとして扱われる様子。ググってみても、Perlの場合のやり方しか見つからず。(ググり方が悪いのかもしれません。)

    {
        local $^W = 0;
        $agent->field( name => $value );
    }

一度諦めて、翌日。そういや、mechanize って ClientForm を使ってたよな、と思って調べ直す。どうやら control には readonly って属性があって、そこは変更可能っぽい。タブキーをアチコチで連打して探っている内にたどりついたのが以下の方法!

In [9]: for i in br.form.controls:
  ....:     i.readonly = False
  ....:     

In [10]: print br.form
<POST https://www.example.com/login application/x-www-form-urlencoded
  <HiddenControl(username=)>
  <HiddenControl(password=)>>

キタコレ!readonlyじゃなくなってるよ、ママン!ということで、早速、ログイン再チャレンジ

In [11]: br['username'] = 'foo'

In [12]: br['password'] = 'bar'

In [13]: br.submit()
Out[13]: <response_seek_wrapper at 0x10734e0 (0) whose wrapped object = <closeable_response at 0x123f490 whose fp = <socket._fileobject object at 0x01325D18>>>

おぉおぉ。無事にログイン出来ましたよ。このあたりをもうちょっとキレイにまとめて、社内でこっそり広めよう、そうしよう。mechanizeに乾杯

bonlifebonlife 2007/08/05 10:43 よくよく見たら、

br.form.set_all_readonly(False)

でOKでしたね…orz

http://wwwsearch.sourceforge.net/ClientForm/

スパム対策のためのダミーです。もし見えても何も入力しないでください
ゲスト


画像認証