Python mechanize - 两个类型为“提交”的按钮

29 投票
4 回答
31887 浏览
提问于 2025-04-15 11:06

我有一个用Python写的脚本,它可以自动填写网页表单,并且应该点击“创建”按钮。但是遇到了一个问题,这个表单有两个按钮。一个是“添加附件”,另一个是“创建”。这两个按钮都是提交按钮,而“添加附件”按钮是第一个列出的。所以当我选择表单并执行 br.submit() 时,它点击的是“添加附件”按钮,而不是“创建”按钮。我在网上查了很多资料,但没有找到有用的方法来选择表单中的特定按钮。有没有人知道怎么跳过第一个“提交”按钮,直接点击第二个按钮的方法?

4 个回答

5

使用'click'方法。例如:

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

这样应该可以正常工作。

7

我建议你使用Twill,它是基于mechanize的(大部分是经过修改的)。

假设你有一个表单,里面有一些字段和两个提交按钮,按钮的名字分别是“submit_to_preview”和“real_submit”。下面的代码应该可以正常工作。

顺便提一下,这段代码不是线程安全的,所以如果你打算在多线程环境中使用它,最好加上锁。

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

希望这能帮到你。祝好!

22

我尝试使用nr参数,但没有成功。

我发现用name和label这两个参数组合可以成功,其中“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')

还有一种变体也对我有效,就是两个提交按钮的“name”相同,比如:

<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 />... 更奇怪的是,我在两个提交按钮之间不能有任何东西。

我花了两个多小时寻找的mechanize/ClientForm的bug,最后竟然是因为这个原因:

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

在多行上工作正常(这本不该有影响)。

我喜欢mechanize,因为它安装简单(只需把文件复制到我的包含目录)而且使用起来也很方便,但如果我没有漏掉什么大问题的话,我觉得这样的bug实在让人失望 - 我想不出任何合理的理由,为什么第一个例子会失败,而第二个却能成功。

顺便提一下,我还发现了另一个mechanize的bug,里面的<textarea>如果放在<p>标签内,就不会被识别为有效控件,但一旦把它移出<p>容器,它就能正常识别。而且我检查过,textarea确实可以放在其他块级元素里,比如<p>

撰写回答