如何使用带过滤的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方法实现相同的功能吗?我想如果可能的话会简单很多。

最简单的方法是使用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中导航并找到url 如果你知道它们在哪里,否则你只是在黑暗中拍摄,应该使用像URI.extract这样的东西,因为它经过了良好的测试,有许多模式可以识别,并允许您自定义想要找到的内容。不使用它会让你重新发明轮子。

您的测试,寻找a/@href将找到锚与href参数,但这些不一定是url,因为JavaScript动作也可以住在那里。

如果使用Nokogiri,只想在<a> href中查看,我会这样做:

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"]

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

n['href']是获取节点参数值的Nokogiri简写。

[.html$/]是一个字符串快捷方式,用于对该字符串应用regex匹配。

看你写的东西:

page.xpath("//a/@href").map{|item| item.value if item.value =~ /.*.html$/ }.compact

由于map中的if条件,您必须使用compact来清除数组中不需要的/意外的nil值。不要那样做;当你不需要这样写的时候,它就是反动的和防御性的编程。相反,使用selectreject来处理条件测试,然后只将可接受的节点提供给map,然后将它们转换:

doc.search('a[href]').select{ |n| n['href'][/.html$/] }.map{ |n| n['href'] }

相关内容

  • 没有找到相关文章

最新更新