您的 XPath 中有一个错误,而且限制性太强:
search("/html/head/meta[(@property='og:title']")
应该:
search("/html/head/meta[@property='og:title']")
修复错误。我将其简化为:
search("//meta[@property='og:title']")
另外,你想做什么也不是很清楚。你想找
<meta
property="og:title"
content="Explore the Titanic Wreck Site via Social Media [EXCLUSIVE]"
/>
并提取content
参数?还是要定位标签,确认包含"og:title"
属性标签和"Explore the Titanic Wreck Site via Social Media [EXCLUSIVE]"
内容,再做进一步处理?
也就是说,通常使用 CSS 访问器而不是 XPath 更简单。我更喜欢使用 Nokogiri,它同时具有 XPath 和 CSS 选择器;我在下面使用CSS:
require 'nokogiri'
require 'open-uri'
doc = Nokogiri::HTML(open('http://mashable.com/2010/08/06/expedition-titanic'))
(doc % 'meta[property="og:title"]')
=> #<Nokogiri::XML::Element:0x8084ee48 name="meta" attributes=[#<Nokogiri::XML::Attr:0x8084ed58 name="property" value="og:title">, #<Nokogiri::XML::Attr:0x8084ed1c name="content" value="Explore the Titanic Wreck Site via Social Media [EXCLUSIVE]">]>
Nokogiri 和 Hpricot 分别支持和/
的%
简写。“搜索”返回一个包含所有匹配项的数组,“at”只返回第一个匹配项。因此,上面的示例使用 CSS 获取第一个节点,表明这是正确的轨道。我不确定如何使用 CSS 来匹配同一个标签中的两个参数,所以我将使用 跟踪所有标签,然后根据参数进行过滤:search
at
<meta>
property="og:title"
content=
(doc / 'meta[property="og:title"]').select{ |n| n['content'][/titanic wreck site/i] }
=> [#<Nokogiri::XML::Element:0x8084ee48 name="meta" attributes=[#<Nokogiri::XML::Attr:0x8084ed58 name="property" value="og:title">, #<Nokogiri::XML::Attr:0x8084ed1c name="content" value="Explore the Titanic Wreck Site via Social Media [EXCLUSIVE]">]>]
那时,我们在返回的数组中找到了正确的节点,因此您可以提取任何您想要的内容,或者潜入其子节点并解雇和掠夺。为此,您需要使用.first
或[0]
获取实际节点以进行进一步处理:
(doc / 'meta[property="og:title"]').select{ |n| n['content'][/titanic wreck site/i] }.first
根据 OP 的响应进行更新,仍然使用 Nokogiri:
>> meta = (doc % 'meta[@property="og:title"]')['content']
>> meta #=> "Explore the Titanic Wreck Site via Social Media [EXCLUSIVE]"