Python机械化 - 两个“提交”类型的按钮

时间:2009-04-09 16:11:16

标签: python mechanize

我有一个用python编写的机械化脚本,它填写了一个Web表单,并且应该点击“创建”按钮。但是有一个问题,表单有两个按钮。一个用于“添加附件”,另一个用于“创建”。两者都是“提交”类型,附加按钮是列出的第一个。因此,当我选择论坛并执行br.submit()时,它会点击“附加”按钮而不是“创建”。广泛的谷歌搜索对于选择表单中的特定按钮没有任何帮助。有没有人知道跳过第一个“提交”按钮并点击第二个的任何方法?

4 个答案:

答案 0 :(得分:21)

我尝试使用nr参数,没有任何运气。

我能够使用名称和标签参数的组合来使用它,其中“label”似乎对应于HTML中的“value”:

以下是我的两个提交按钮:

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

...这是点击第一个的代码,返回,然后点击第二个:

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')

重要提示 - 我 只能 / p>

具体来说,我不能拥有<br/> - 相反,我必须拥有<br /> ...而且,更不用说,我在两个提交按钮之间没有任何内容。

让我感到沮丧的是,我在两个多小时内找到的机械化/ 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>

(全部在一行上)不起作用,但是

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

工作正常(在多行上,也不应该重要)。

我喜欢机械化,因为它很容易安装(只是将文件复制到我的include目录中),因为它使用起来非常简单,但除非我遗漏了一些重要内容,否则我认为像这样的错误有点可怕 - 我想不出一个很好的理由,为什么第一个例子应该失败,第二个例子应该有效。

顺便说一句,我还发现了另一个机械化错误,其中<textarea>中包含的<p>未被识别为有效控件,但是一旦将其从{{1}中取出容器它被认可很好。我检查过,textarea 允许包含在<p>等其他块级元素中。

答案 1 :(得分:7)

我建议你使用Twill,它使用机械化(主要是monkeypatched)。 所以说你有一些带有名称“submit_to_preview”和“real_submit”的字段和两个提交按钮。以下代码应该可以工作。

BTW请记住这不是线程安全的,所以如果你想在线程环境中使用代码,你可能想要使用锁。

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")

希望有所帮助。欢呼声。

答案 2 :(得分:4)

使用“点击”方法。 E.g。

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

应该工作。

答案 3 :(得分:2)

我可以根据使用HTTP的经验谈谈,而不是机械化,但我认为这可能是你想要的。

当表单中有两个提交按钮时,服务器可以确定哪个按钮被按下,因为客户端应该为提交按钮添加了一个参数。所以:

<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

取决于按下的按钮。

如果您以编程方式确定要发送的参数,则需要添加一个参数,其中包含已按下的提交按钮的名称,以及它的值。