0

我在 ruby​​ on rails 中使用 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>
4

1 回答 1

0

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

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

<html>
<头部>
<无脚本>
<meta http-equiv="刷新" />
</noscript>
<meta name="norton-safeweb-site-verification" />
</head>
<正文>
<h1>测试</h1>
</正文>
</html>

考虑以下搜索的结果:

#!/usr/bin/env 红宝石

需要“红宝石”
需要“杏”
需要'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 访问器,因此我在示例代码中使用了这些访问器。

搜索任何“元”标签发现了两次。到目前为止,一切都很好。抓住第二个是获得你想要的东西的一种方式。

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

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

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

Hpricot 有一组非常好的 CSS 选择器:

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

现在,说了这么多,建议使用 Nokogiri 而不是 Hpricot。我发现 Hpricot 静默失败但 Nokogiri 成功解析了格式错误的 XML 和 HTML 的情况。

于 2010-04-11T01:24:28.377 回答