在尝试解析具有noscript标记的url时,hpricot会抛出异常

时间:2010-04-08 11:40:21

标签: ruby-on-rails ruby hpricot

我在rails上的ruby中使用hpricot gem来解析网页并提取元标记内容。但是,如果网站在<noscrpit>标记之后有<head>标记,则会引发异常

Exception: undefined method `[]' for nil:NilClass

我甚至尝试将gem更新到最新版本。但仍然是一样的。

这是我使用的示例代码。

require 'rubygems'
require 'hpricot'
require 'open-uri'
begin
       index_page = Hpricot(open("http://sample.com"))
       puts index_page.at("/html/head/meta[@name='verification']")['content'].gsub(/\s/, "")
rescue Exception => e
       puts "Exception: #{e}"
end

我想在将网页提供给hpricot之前删除noscript标签。 或者还有其他办法吗?

我的html代码段

<html> 
<head> 
<noscript> 
<meta http-equiv="refresh" content="0; url=http://www.yoursite.com/noscripts.html"/> 
</noscript> 
<meta name="verification" content="7ff5e90iormq5niy6x98j75-o1yqwcds-c1b1pjpdxt3ngypzdg7p80d6l6xnz5v3buldmmjcd4hsoyagyh4w95-ushorff60-f2e9bzgwuzg4qarx4z8xkmefbe-0-f" /> 
</head> 
<body> 
<h1>Testing</h1> 
</body> 
</html>

1 个答案:

答案 0 :(得分:0)

我不能用Hpricot复制异常。但是,我确实看到了您尝试查找元标记的问题。

我缩短了HTML示例,以帮助我的示例代码放入此处的答案框,然后在本地保存HTML,以便我可以使用open-uri来获取它。

<html> 
<head> 
<noscript> 
<meta http-equiv="refresh" /> 
</noscript> 
<meta name="norton-safeweb-site-verification" /> 
</head> 
<body> 
<h1>Testing</h1> 
</body> 
</html>

考虑以下搜索结果:

#!/usr/bin/env ruby

require 'rubygems'
require 'hpricot'
require 'open-uri'

doc = Hpricot(open('http://localhost:3000/test.html'))

(doc / 'meta').size # => 2
(doc / 'meta')[1] # => {emptyelem <meta name="norton-safeweb-site-verification">}

(doc % 'meta[@name]') # => {emptyelem <meta name="norton-safeweb-site-verification">}

(doc % 'meta[@name="verification"]') # => nil
(doc % 'meta[@name*="verification"]') # => {emptyelem <meta name="norton-safeweb-site-verification">}

(doc % 'meta[@name="norton-safeweb-site-verification"]') # => {emptyelem <meta name="norton-safeweb-site-verification">}

请记住,Hpricot中的'/'表示.search()或“查找所有出现次数”,'%'表示.at()或“查找第一次出现”。使用长路径到达所需元素通常不太可能找到您想要的内容。在元素或其兄弟姐妹或父母中寻找独特的东西。长访问器更容易破解,因为在搜索时会考虑页面的前面布局;如果页面中的某些内容发生更改,则访问者将无效,因此可以原子搜索或在最小的元素组中搜索。此外,Hpricot文档建议使用CSS访问器,所以我在示例代码中使用它们。

搜索任何'meta'标签时发现了两次。到现在为止还挺好。抓住第二个是获得你想要的东西的一种方式。

搜索“带有名称参数的元素”找到了目标。

搜索“名称参数由'验证'组成的元”失败,因为没有。使用“* =”在参数内搜索。

搜索“名称参数由'norton-safeweb-site-verification'组成的元”成功,因为这是完整的参数值。

Hpricot有一套相当不错的CSS选择器:

http://wiki.github.com/whymirror/hpricot/supported-css-selectors

现在,所有这一切,建议使用Nokogiri而不是Hpricot。我发现Hpricot无声失败但Nokogiri成功解析格式错误的XML和HTML的案例。