如何使用Nokogiri从HTML头部获得规范链接



我正在尝试从使用Nokogiri的网页中获得定义的规范链接:

<link rel="canonical" href="https://test.com/somepage">

我要找的是href

不管我怎么试,似乎都不起作用。这是我的文件:

page = Nokogiri::HTML.parse(browser.html)
canon = page.xpath('//canonical/@href')
puts canon 

这不会返回任何东西,甚至没有错误。

您试图获得属性,但不是这样做的。

你可以这样写:

page.xpath('//link[@rel="canonical"]/@href')

它说的是:在文档的任何地方给我一个链接元素,它的rel属性等于"canonical",当你找到那个节点时,给我它的href属性。

完整答案为:

page = Nokogiri::HTML.parse(browser.html)
canon = page.xpath('//link[@rel="canonical"]/@href')
puts canon 

您尝试做的是获得一个称为"canonical"的节点,而不是属性。

我喜欢使用CSS选择器而不是XPath,因为它们更具可读性:

require 'nokogiri'
doc = Nokogiri::HTML('<link rel="canonical" href="https://test.com/somepage">')
doc.at('link[rel="canonical"]')['href'] # => "https://test.com/somepage"

对于Nokogiri和XPath在访问节点参数时返回的内容存在混淆。想想看:

require 'nokogiri'
doc = Nokogiri::HTML('<link rel="canonical" href="https://test.com/somepage">')
下面是我使用CSS的方法:
doc.at('link[rel="canonical"]').class # => Nokogiri::XML::Element
doc.at('link[rel="canonical"]')['href'].class # => String
doc.at('link[rel="canonical"]')['href'] # => "https://test.com/somepage"

XPath虽然更强大,但也能够让您或Nokogiri、Ruby或CPU做更多的工作。

首先是xpath,它是search的xpath特定版本,返回NodeSet,而不是节点或元素。NodeSet类似于节点数组,如果您不知道自己得到了什么,可能会受到影响。来自NodeSet文档:

NodeSet包含Nokogiri::XML::Node对象的列表。通常,Nokogiri::XML::Searchable#css或Nokogiri::XML::Searchable#xpath

搜索文档的结果返回Nokogiri:: Searchable#xpath

如果您正在寻找一个特定的节点,或者只是特定类型节点的单个实例,那么使用at,或者如果您想要挑剔,使用at_cssat_xpath。(当你使用atsearch时,Nokogiri通常可以理解你的意思,但有时你必须使用特定的方法来推动Nokogiri朝正确的方向前进。)在上面的示例中使用at显示它返回节点本身,一旦获得了节点,通过将其作为散列处理来获取任何参数的值就很简单了。

xpath, searchcss都返回NodeSets,因此,像数组一样,您需要指向您想要的实际元素,然后访问参数:

doc.xpath('//link[@rel="canonical"]/@href').class # => Nokogiri::XML::NodeSet
doc.xpath('//link[@rel="canonical"]/@href').first.class # => Nokogiri::XML::Attr
doc.xpath('//link[@rel="canonical"]/@href').text # => "https://test.com/somepage"

注意'//link[@rel="canonical"]/@href'导致Nokogiri返回一个Attr对象,而不是文本。您可以打印该对象,Ruby将对其进行字符串化,但如果您试图将其视为字符串,则它的行为不会像字符串那样导致错误。例如:

doc.xpath('//link[@rel="canonical"]/@href').first.downcase # => NoMethodError: undefined method `downcase' for #<Nokogiri::XML::Attr:0x007faace115d20>

相反,使用textcontent来获取文本值:

doc.at('//link[@rel="canonical"]/@href').class # => Nokogiri::XML::Attr
doc.at('//link[@rel="canonical"]/@href').text # => "https://test.com/somepage"

或者获取元素本身,然后像访问散列一样访问参数:

doc.at('//link[@rel="canonical"]').class # => Nokogiri::XML::Element
doc.at('//link[@rel="canonical"]')['href'] # => "https://test.com/somepage"

都将返回一个String。

还请注意,在本例中,我没有使用@href返回Attr,我只获取节点本身,然后使用['href']返回参数的文本。它是一个更短的选择器,更有意义,至少对我来说,因为Nokogiri不必返回Attr对象,然后你必须使用text转换,或者当你意外地将其视为字符串时可能会遇到问题。

相关内容

  • 没有找到相关文章

最新更新