2009-04-09 78 views
27

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

回答

21

我尝试使用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 /> ......而且,更不用说,我在两个提交按钮之间没有任何东西。

它沮丧我没有尽头的机械化/ 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> 

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

我喜欢机械化,因为它很容易安装(只需将文件复制到我的包含目录中),因为它非常易于使用,但除非我错过了一些重要的东西,我认为这样的错误有点糟糕 - 我根本无法想出一个很好的理由,为什么第一个例子会失败,第二个例子应该失败。

而且,顺便说一句,我也发现了其中所包含一个<p>内的<textarea>不被识别为有效控制另一机械化的错误,但一旦你把它拿出来<p>容器它承认就好了。我检查了,textarea 允许包含在其他块级元素,如<p>

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> 

将带你要么网址:

blah?button_1=One 

或:

blah?button_2=Two 

根据被按下按钮。

如果您正在编程确定要发送的参数,则需要添加一个参数,其中包含按下的提交按钮的名称,并且它是值。

7

我建议你使用使用机械化(主要是monkeypatched)的斜纹。 所以说你有一些字段和两个提交按钮名称“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") 

希望有帮助。干杯。

4

使用'click'方法。例如。

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

应该工作。