使用Mechanize查找下一个输入元素?

时间:2013-03-29 03:53:12

标签: ruby mechanize

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

3 个答案:

答案 0 :(得分:3)

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

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

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访问器来查找页面中“email”的位置。完成后,您可以找到下一个<input>标记。

从一个简单的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">]>

在此基础上,这会获得<input>标记:

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表单正常运行,它必须具有元素的名称。那些在提交表单时传递给服务器。如果没有这些名称,确定哪些输入发送了特定的数据需要花费很多工作,并且程序员很懒,我们不想努力工作,所以你可以指望有一个名字可以使用。 / p>

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

答案 1 :(得分:2)

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

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'

答案 2 :(得分:1)

对于格式正确的 HTML页面,input元素应该label显示input的内容。在这种情况下,您可以迭代所有label,找到包含文本"email"的{​​{1}},并通过input的{​​{1}}属性获取关联的for

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

如果你的意思是for正好在DOM中的某个元素之后。您可以执行一些DOM遍历来查找包含input的元素旁边是否有"email"元素。

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