使用Mechanize gem根据它们在DOM中的位置返回链接集合

时间:2012-05-08 13:11:14

标签: ruby nokogiri mechanize

我正在努力进行机械化。我希望“点击”一组链接,这些链接只能通过它们的位置(div#content中的所有链接)或它们的href来识别。

我已经尝试过上述两种识别方法但没有成功。

从文档中,我无法弄清楚如何根据它们在DOM中的位置返回链接集合(用于单击),而不是直接在链接上返回属性。

其次,documentation建议你可以使用:href匹配部分href,

page = agent.get('http://foo.com/').links_with(:href => "/something")

但我能够让它返回链接的唯一方法是传递一个完全限定的URL,例如

page = agent.get('http://foo.com/').links_with(:href => "http://foo.com/something/a")

如果我想返回带有href的

的链接集合,这不是很有用
http://foo.com/something/a
http://foo.com/something/b
http://foo.com/something/c
etc...

我做错了吗?我有不切实际的期望吗?

3 个答案:

答案 0 :(得分:8)

第二部分 您传递给的值:href默认情况下必须是完全匹配。因此,示例中的href仅匹配<a href="/something"></a>而不是<a href="foo.com/something/a"></a>

你想要做的是传入一个正则表达式,以便它匹配href字段中的子字符串。像这样:

page = agent.get('http://foo.com/').links_with(:href => %r{/something/})

修改 第一部分 要使其仅在链接中选择链接,请在字符串中添加nokogiri样式的搜索方法。像这样:

page = agent.get('http://foo.com/').search("div#content").links_with(:href => %r{/something/})    # **

好吧,这不起作用,因为你执行page = agent.get('http://foo.com/').search("div#content")之后会得到一个Nokogiri对象而不是机械对象,所以links_with将不起作用。但是,您将能够使用css方法从Nokogiri对象中提取链接。我会建议像:

page = agent.get('http://foo.com/').search("div#content").css("a")

如果这不起作用,我建议您查看http://nokogiri.org/tutorials

答案 1 :(得分:2)

第n个链接:

page.links[n-1]

前5个链接:

page.links[0..4]

与href中的'something'链接:

page.links_with :href => /something/

答案 2 :(得分:1)

您可以使用nokogiri节点获取机械化链接。请参阅source code of links() method.

# File lib/mechanize/page.rb, line 352
def links
  @links ||= %w{ a area }.map do |tag|
    search(tag).map do |node|
      Link.new(node, @mech, self)
    end
  end.flatten
end

这意味着:

the_links= page.search("valid_selector").map do |node|
  Mechanize::Page::Link.new(node, agent, page)
end

这将为您提供有用的href,text和uri方法。