原文标题:Processing HTML with Hpricot
原文作者:madpilot
原文地址:http://www.sitepoint.com/blogs/2 ... -html-with-hpricot/
译者:cclong
译文首发:http://www.ruby-lang.org.cn/forums/thread-2422-1-1.html
在Web2.0世界里聚合(mashups)和简单API访问使从第三方站点提取数据来重新聚合(re-mash)到新项目中变得多么容易。不幸的是,不是每个人都被它的bug所害。我们开发者不得不做多一点工作来获取我们需要的信息。通常称这技术为“网页抓取”(screen scrape), 你的程序扮演
浏览器角色访问第三方服务器并转换接收的HTML。
按道理,这应当非常简单,但只有那些曾经试图通过正则表达式检索标签的人来说,才明白这是件很痛苦的事情。幸运的是,我们ruby程序员有解决麻烦的HTML解释的库:Hpricot library。Hpricot允许开发者通过CSS-selectors和X-Path访问html元素,因此你很轻松就可以明确目标标记,还有它是用C语言写的,因此相当快。
安装
Hpricot 是一个gem,因此安装很简单。
需要调用这个库的时候只需要在ruby文件的顶部添加下面代码:
使用
让我们看看下面这个HTML片断:
<html>
<head>
<title>Snippet</title>
</head>
<body>
<div id="container">
<div id="navigation">
<ul>
<li><a href="/">Home</a></li>
<li><a href="/contact></a></li>
</ul>
</div>
<div id="sub-content">
<p>This would be some sort of sidebar</p>
</div>
<div id="content">
<p>This is paragraph 1</p>
<p>This is paragraph 2</p>
</div>
</div>
</body>
</html>
我们能轻易从段落中抓取数据(假设这个HTML网页数据已经储藏在@html变量中)
doc = Hpricot(@html)
pars = Array.new
doc.search("div[@id=content]/p").each do |p|
pars << p.inner_html
end 是的,这样就解决了上面的问题。现在你数组里已经有2个元素就像从两个p标记里复制的一样。注意到在sub-content层的p标记没有抓取?
不但如此,你还能操纵HTML-如果你需要,它就能派上用场。比如,创建一个快速但粗劣(quick and dirty)的灵巧版本。如果我们想从灵巧版本去掉sub-content层,我们可以这样做:
doc = Hpricot(@html)
doc.search("div[@id=sub-content]").remove
puts doc 输出的HTML结果不再有sub-content层!
添加新类到导航ul元素,也是很简单:
doc = Hpricot(@html)
doc.search("div[@id=navigation]/ul").set("class", "nav") 这只是冰山一角-这个库真的非常强大并且容易使用。官方网页有更多(有意义)的例子。
免责声明:你在抓取别人网页数据之前请确认已得到对方负责人的准许。
[
本帖最后由 cclong 于 2007-12-13 10:25 编辑 ]