如何使用带过滤的nokogiri提取链接

时间:2014-05-28 23:04:54

标签: ruby xpath nokogiri

我想在这样的文档中获取所有*.html个链接。

require 'open-uri'
page = Nokogiri::HTML(open "http://example.com")
page.xpath("//a/@href").map{|item| item.value if item.value =~ /.*.html$/ }.compact

我可以使用xpath方法实现相同的功能吗? 我认为如果可能的话会更简单。

1 个答案:

答案 0 :(得分:4)

最简单的方法是使用Ruby的URI类并使用extract方法:

require 'uri'

html = '
<html>
<body>
http://foo.bar.com
mailto://foo@bar.com
</html>
'
URI.extract(html) # => ["http://foo.bar.com", "mailto://foo@bar.com"]

这并不解析HTML,而是使用正则表达式来查找类似URL的模式。它有点容易出错,但简单快捷。

除此之外,您可以轻松浏览XML并查找网址 IF 您知道它们在哪里,否则您只是在黑暗中拍摄并应使用{ {1}}因为它经过了良好的测试,具有许多可识别的模式,并允许您自定义要查找的内容。不使用它将导致你重新发明那个轮子。

您的测试,查找URI.extract会找到包含a/@href参数的锚点,但这些参数不一定是URL,因为JavaScript操作也可以在那里生效。

如果使用Nokogiri并且只想查看href hrefs,我会做类似的事情:

<a>

这使用CSS而不是XPath,这通常会产生更易读的选择器。

require 'nokogiri' html = ' <html> <body> <p><a href="http://foo.bar.com/index.html">foo</a></p> <p><a href="mailto://foo@bar.com">bar</a></p> </html> ' doc = Nokogiri::HTML(html) doc.search('a[href]').select{ |n| n['href'][/\.html$/] }.map{ |n| n['href'] } # => ["http://foo.bar.com/index.html"] 是Nokogiri的简写,用于获取节点参数的值。

n['href']是一个字符串快捷方式,用于将正则表达式匹配应用于该字符串。

看看你写的是什么:

[\.html$/]

由于page.xpath("//a/@href").map{|item| item.value if item.value =~ /.*.html$/ }.compact 中的compact条件限制,您必须使用nil来清除数组中不需要/意​​外的if值。不要这样做;当你不需要这样写时,它是反动和防御性的编程。相反,请使用mapselect来处理条件测试,然后将可接受的节点提供给reject,然后将其转换为:{/ p>

map