29

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

4

4 回答 4

22

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

我能够让它与名称和标签参数的组合一起使用,其中“标签”似乎对应于 HTML 中的“值”:

这是我的两个提交按钮:

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

重要提示 -在清理页面其余部分的一些 HTML后,我只能让任何这个多提交按钮代码工作。

具体来说,我不能拥有<br/>——相反我必须拥有<br />......而且,更没有意义的是,我不能在两个提交按钮之间拥有任何东西。

我追了两个多小时的 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>

(都在一条线上)没有用,但是

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

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

我喜欢 mechanize 因为它很容易安装(只需将文件复制到我的包含目录中)并且因为它非常易于使用,但除非我错过了一些重要的东西,否则我认为像这样的错误有点可怕 - 我可以'根本想不出为什么第一个例子应该失败而第二个例子应该工作的充分理由。

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

于 2009-11-06T06:17:16.903 回答
7

我建议你使用使用机械化(主要是猴子补丁)的斜纹。所以说你有一些字段的表单和两个名为“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")

希望有帮助。干杯。

于 2009-04-09T16:50:55.797 回答
5

使用“点击”方法。例如

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

应该管用。

于 2009-08-11T23:10:18.520 回答
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

取决于按下哪个按钮。

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

于 2009-04-09T16:28:42.213 回答