Hpricot搜索如何

时间:2010-12-03 15:37:22

标签: ruby xpath hpricot

我想在网页上进行搜索,如果我有结果而不是我需要一个属性。 这是网页:link text

我感兴趣的是,meta的标题是属性,其值为“og:title”ot也不是,如果我想要内容

如果我们查看页面的来源,它有一个药水:

<meta
property="og:title" content="Explore the Titanic Wreck Site via Social Media [EXCLUSIVE]" />

所以我想要一个真实的结果og:标题查询和探索泰坦尼克号沉船遗址通过社交媒体[EXCLUSIVE]值进行下一次搜索,如何正确地进行

search("/html/head/meta[(@property='og:title']")没有返回我想要的内容。

任何建议?

3 个答案:

答案 0 :(得分:2)

使用:

/html/head/meta[@property='og:title']/@content

答案 1 :(得分:1)

你的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分别支持/%的{​​{1}}和search简写。 “搜索”返回所有匹配的数组,“at”仅返回第一个匹配。因此,上面的示例使用CSS获取第一个节点,显示这是正确的轨道。我不确定如何使用CSS匹配同一标记中的两个参数,因此我将使用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]

基于OP的回复更新,使用Nokogiri仍然:

(doc / 'meta[property="og:title"]').select{ |n| n['content'][/titanic wreck site/i] }.first

答案 2 :(得分:1)

感谢您的回答。 当我发布我的问题时,我无法意识到我在搜索中有错误。那是周五晚上......

正确的搜索是

elements = @doc.search("/html/head/meta[@property='og:title']")
  • 在@property
  • 之前从表达式中删除(个字符

这给出了:

elements = <meta property="og:title" content="Explore the Titanic Wreck Site via Social Media [EXCLUSIVE]" />

结果。 比我检查我是否有东西,如果有的话,比我需要的内容值

if elements.nil?
   puts 'not found'
  elsif elements.size > 0
    puts "Found one, og:title = #{elements}" 
    content = elements.attr("content");
    puts content # this will display the content ( it will be processed)
  else
    ... can come here the flow control? - theoretically yes, but in practice?
  end