我想在这样的文档中获取所有*.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
方法实现相同的功能吗?
我认为如果可能的话会更简单。
答案 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
值。不要这样做;当你不需要这样写时,它是反动和防御性的编程。相反,请使用map
或select
来处理条件测试,然后将可接受的节点提供给reject
,然后将其转换为:{/ p>
map