【问题标题】:Finding next input element using Mechanize?使用机械化查找下一个输入元素?
【发布时间】:2013-03-29 03:53:11
【问题描述】:

使用Mechanize,是否可以在页面的HTML中找到一个短语,例如“email”,然后找到下一个<input*,然后填写那个输入字段,并且只填写那个字段?

【问题讨论】:

    标签: ruby mechanize


    【解决方案1】:

    Mechanize 在内部使用 Nokogiri 来处理其 DOM 解析,这是它能够在页面中定位不同元素的基础。

    可以访问已解析的 DOM,并且通过它使用 Nokogiri 来定位 Mechanize 通常不会让我们找到的元素。例如:

    require 'mechanize'
    
    agent = Mechanize.new
    page = agent.get('http://www.example.com')
    
    # Use Nokogiri to find the content of the <h1> tag...
    puts page.at('h1').content # => "Example Domain"
    

    对于您的搜索,您需要使用 XPath 访问器来定位“电子邮件”在页面中的位置。完成后,您可以找到下一个 &lt;input&gt; 标记。

    从一个简单的 HTML 片段开始,我们假设它来自 Mechanize:

    page = Nokogiri::HTML('<div><form><p>email</p><input name="email"></form></div>')
    puts page.to_html
    

    看起来像:

    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
    <html><body><div><form>
    <p>email</p>
    <input name="email">
    </form></div></body></html>
    

    搜索“电子邮件”:

    page.at("//*[contains(text(),'email')]")
    #<Nokogiri::XML::Element:0x3ff50d0c4bc0 name="p" children=[#<Nokogiri::XML::Text:0x3ff50d0c497c "email">]>
    

    在此基础上,得到&lt;input&gt; 标签:

    input_tag = page.at("//*[contains(text(),'email')]/following-sibling::input")
    #<Nokogiri::XML::Element:0x3ff50d09b75c name="input" attributes=[#<Nokogiri::XML::Attr:0x3ff50d09b5f4 name="name" value="email">]>
    

    找到输入标签后,您可以使用 Nokogiri 从标签中获取“名称”,然后告诉 Mechanize 定位并填写该特定输入字段:

    input_tag['name']
    => "email"
    

    要使 Web 表单正常运行,它必须具有元素的名称。这些在提交表单时被传递到服务器。如果没有名称,则需要大量工作才能确定哪个输入发送了特定的数据,而且,程序员很懒,我们不想努力工作,所以你可以指望有一个可以使用的名称。

    有关更多信息,请参阅“Ruby Mechanize, Nokogiri and Net::HTTP”以及a search of Stack Overflow,阅读Nokogiri documenation and tutorials将为您提供大量所需信息,帮助您了解如何完成其​​余工作。

    【讨论】:

    • 真的很抱歉回复晚了,我的病好了。感谢您为回答所付出的所有努力,这真的很有帮助:) 现在一切正常。再次感谢! :)
    【解决方案2】:

    首先找到带有短语文本的元素:

    el = page.at('*[text()*="some phrase"]')
    

    从那里您可以获得以下第一个输入:

    input = el.at('./following::input')
    

    现在,找到该输入的祖先表单节点:

    form_node = input.ancestors('form')[0]
    

    然后用它来获取 Mechanize::Form 对象

    form = page.form_with(:form_node => form_node)
    

    现在你可以填写值了

    form[input[:name]] = 'foo'
    

    【讨论】:

      【解决方案3】:

      对于一个格式良好的 HTML 页面,input 元素应该有一个label 显示input 的用途。在这种情况下,您可以遍历所有label,找到包含文本"email" 的那一个,并通过labelfor 属性获取关联的input

      然而,并不是所有的 HTML 页面都是格式良好的。没有label、没有for 属性或其他格式不正确的问题。

      如果您指的是 DOM 中某个元素之后的 input。你可以做一些 DOM 遍历来查找包含 "email" 的元素旁边是否有一个 input 元素。

      如果您指的是呈现页面中某个元素旁边的input,您应该定义“旁边”的内容。而且我认为如果不付出很大的努力,您将无法获得想要的东西。某些位于元素“email”之后的元素可能会通过一些 CSS 技巧放置在它之前。您需要一些图形 API 才能找到 input。但是,我在 watir 的 API 文档中没有看到这一点。

      【讨论】:

        猜你喜欢
        • 2012-10-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-10-26
        • 1970-01-01
        相关资源
        最近更新 更多