用Hpricot编写的Ruby HTML scraper在转义HTML时出现问题

时间:2010-05-10 01:48:37

标签: ruby html-parsing escaping open-uri html-entities

我正试图抓住这个页面:http://www.udel.edu/dining/menus/russell.html。我使用Hpricot库在Ruby中编写了一个刮刀。

问题:HTML页面已转义,我需要将其显示为未转义

example: "M&M" should be "M&M"  
example: "Entrée" should be "Vegetarian Entrée"  

我尝试过使用Ruby中的CGI库(不太成功)和我通过this Stack Overflow帖子找到的HTMLEntities gem。

HTMLEntities在测试期间有效:

require 'rubygems' 
require 'htmlentities'
require 'cgi'

h = HTMLEntities.new
puts "h.decode('Entrée') = #{h.decode("Entrée")}"

blank = " "
puts "h.decode blank = #{h.decode blank}"
puts "CGI.unescapeHTML blank = |#{CGI.unescapeHTML blank}|"

puts "h.decode '<th width=86 height=59 scope=row>Vegetarian Entr&eacute;e</th> ' = |#{h.decode '<th width=86 height=59 scope=row>Vegetarian Entr&eacute;e</th> '}|"  

正确产生

h.decode('Entr&eacute;e') = Entrée
h.decode blank =  
CGI.unescapeHTML blank = |&nbsp;|
h.decode '<th width=86 height=59 scope=row>Vegetarian Entr&eacute;e</th> ' = |<th width=86 height=59 scope=row>Vegetarian Entrée</th> |

但是,当我在open-uri文件上使用它时,它无法正常工作:

require 'rubygems'
require 'hpricot'
require 'open-uri'
require 'htmlentities'
require 'cgi'
f = open("http://www.udel.edu/dining/menus/russell.html")
htmlentity = HTMLEntities.new
while line = f.gets
  puts htmlentity.decode line
end

错误地产生如下内容:

<th width="60" height="59" scope="row">Vegetarian Entrée</th>

<th scope="row"> </th>  // note: was originally '&nbsp;' to indicate a blank

但通过屈服正确处理M&amp; M:

<td valign="middle" class="menulineA">M&M Brownies</td>

我是否错误地处理了转义的HTML?我不明白为什么它在某些情况下有效而在其他情况下无效。

我正在运行ruby 1.8.7(2009-06-12 patchlevel 174)[i486-linux]

任何帮助/建议表示赞赏。感谢。

1 个答案:

答案 0 :(得分:0)

HTMLEntities似乎有效但你有编码问题。您正在打印的终端可能是由您的脚本输出的utf-8字符上的拉丁字符集和barf设置的。

你在什么环境下运行ruby?

'&amp;'的原因正确显示它是一个ascii字符,因此在大多数编码中显示相同。问题是它不应该单独发生在xml文档中,并且可能在以后将解码文件提供给hpricot时出现问题。我相信正确的方法是用hpricot解析然后将你从文档中提取的内容传递给HTMLEntity。