web-dev-qa-db-ja.com

Python mechanize-タイプ 'submit'の2つのボタン

pythonで記述された、Webフォームに入力し、「作成」ボタンをクリックすることになっている機械化スクリプトがあります。しかし、問題があります。フォームには2つのボタンがあります。1つは「追加」用です。添付ファイル 'と'作成 '用。どちらもタイプ'送信 'で、添付ボタンが最初に表示されます。フォーラムを選択してbr.submit()を実行すると、[添付]ボタンをクリックします。 「作成」の代わりに。広範なグーグルでは、フォーム内の特定のボタンを選択するのに役立つものは何もありません。最初の「送信」ボタンをスキップして2番目のボタンをクリックする方法を知っている人はいますか。

27
directedition

運が悪かったので、nrパラメーターを使用してみました。

名前とラベルのパラメータの組み合わせで動作させることができました。「ラベル」はHTMLの「値」に対応しているようです。

これが私の2つの送信ボタンです:

<input type="submit" name="Preview" value="Preview" />
<input type="submit" name="Create" value="Create New Page" />

...そして、最初のコードをクリックして戻り、2番目のコードをクリックするコードは次のとおりです。

from mechanize import Browser
self.br = Browser()
self.br.open('http://foo.com/path/to/page.html')
self.br.select_form(name='my_form')
self.br['somefieldname'] = 'Foo'
submit_response = self.br.submit(name='Preview', label='Preview')
self.br.back()
self.br.select_form(name='my_form')
self.br['somefieldname'] = 'Bar'
submit_response = self.br.submit(name='Create', label='Create New Page')

送信ボタンの「名前」が同じである、私にとっても機能するバリアントがあります。たとえば、次のようになります。

<input type="submit" name="action" value="Preview" />
<input type="submit" name="action" value="Save" />
<input type="submit" name="action" value="Cancel" />

そして

self.br.select_form(name='my_form')
submit_response = self.br.submit(name='action', label='Preview')
self.br.back()
submit_response = self.br.submit(name='action', label='Save')

重要な注意-私はのみこの複数送信ボタンコードのいずれかを機能させることができましたいくつかのHTMLをクリーンアップしましたページの残りの部分。

具体的には、<br/>を使用することはできませんでした。代わりに<br />を使用する必要がありました。さらに意味がないのですが、2つの送信ボタンの間に何も配置できませんでした。

私が2時間以上探していたmechanize/ClientFormのバグが、これに要約されることは、私を際限なく苛立たせました。

<tr><td colspan="2"><br/><input type="submit" name="Preview" value="Preview" />&nbsp;<input type="submit" name="Create" value="Create New Page" /></td></tr>

(すべて1行で)機能しませんでしたが

<tr><td colspan="2"><br />
<input type="submit" name="Preview" value="Preview" />
<input type="submit" name="Create" value="Create New Page" /></td></tr>

正常に動作しました(複数の行で、これも問題ではないはずです)。

インストールが簡単で(ファイルをインクルードディレクトリにコピーするだけ)、使い方もとても簡単なので、mechanizeが好きですが、大きなものがない限り、このようなバグはひどいものだと思います。最初の例が失敗し、2番目の例が機能する理由を考えてみてください。

また、偶然にも、<textarea>内に含まれている<p>が有効なコントロールとして認識されない、別の機械化バグを発見しましたが、<p>コンテナから取り出すとうまく認識されました。そして、textarea is<p>のような他のブロックレベルの要素に含めることが許可されていることを確認しました。

21
Chirael

Mechanize(主にmonkeypatched)を使用するTwillを使用することをお勧めします。つまり、いくつかのフィールドと、names "submit_to_preview"と "real_submit"の2つの送信ボタンがあるフォームがあるとします。次のコードが機能するはずです。

ところで、これはスレッドセーフではないため、スレッド環境でコードを使用する場合に備えて、ロックを使用することをお勧めします。

import twill.commands
b = twill.get_browser()
url = "http://site/myform"
twill.commands.go(url)
twill.commands.fv("2", "name", "Me")
twill.commands.fv("2", "age", "32")
twill.commands.fv("2", "comment", "useful article")
twill.commands.browser.submit("real_submit")

お役に立てば幸いです。乾杯。

7
Shekhar

'クリック'メソッドを使用します。例えば。

mybrowser.select_form(nr=0)
req = mybrowser.click(type="submit", nr=1)
mybrowser.open(req)

動作するはずです。

4
Kyle

機械化するのではなく、HTTPを使った経験から話すことができますが、これはおそらくあなたが望むものだと思います。

フォームに2つの送信ボタンがある場合、クライアントは送信ボタンの引数を追加する必要があるため、サーバーはどちらが押されたかを判別できます。そう:

<form action="blah" method="get">
    <p>
        <input type="submit" name="button_1" value="One" />
        <input type="submit" name="button_2" value="Two" />
    </p>
</form>

次のURLのいずれかを取得します。

blah?button_1=One

または:

blah?button_2=Two

押されたボタンによって異なります。

送信する引数をプログラムで決定する場合は、押された送信ボタンの名前とその値を使用して引数を追加する必要があります。

2
SpoonMeiser