【问题标题】:Python mechanize - two buttons of type 'submit'Python mechanize - “提交”类型的两个按钮
【发布时间】:2010-10-18 14:32:42
【问题描述】:

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

【问题讨论】:

    标签: python mechanize


    【解决方案1】:

    我尝试使用 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 之后让任何这个多提交按钮代码工作。

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

    我花了两个多小时寻找的 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 因为它很容易安装(只需将文件复制到我的包含目录中)并且因为它非常易于使用,但除非我错过了一些主要的东西,否则我认为像这样的错误有点可怕 -我想不出一个很好的理由为什么第一个例子应该失败而第二个应该工作。

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

    【讨论】:

      【解决方案2】:

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

      希望对您有所帮助。干杯。

      【讨论】:

        【解决方案3】:

        使用“点击”方法。例如

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

        应该可以。

        【讨论】:

          【解决方案4】:

          我可以从使用 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
          

          取决于按下的按钮。

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

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2011-06-29
            • 2016-01-19
            • 2016-01-11
            • 2016-10-10
            • 2020-01-09
            相关资源
            最近更新 更多