IT技术博客大学习 共学习 共进步
全部 移动开发 后端 数据库 AI 算法 安全 DevOps 前端 设计 开发者

Ruby 解析 HTML (Nokogiri)

qingbo.blog 2010-06-01 13:05:04 累计浏览 4,948 次
本机暂存

很多时候我们需要爬取网页并且获取页面上的特定内容,不一定是做坏事比如爬取竞争对手的数据。也许我想定期爬自己的网站,找到页面上的链接,并且看它们指向的网页是不是都还可以访问。爬到一个网页,为了获得上面所有的链接,我以前首先想到的是用正则表达式。但是 HTML 并不一定是良构的 XML (如果每个人都用 XML 的标准写 HTML,那我们直接用标准的 XML parser 就好了),写正则表达式的时候你需要考虑大小写、换行、单引号/双引号/没有引号、某些地方的空格,太头疼了。

更好的办法当然是像在浏览器中使用 JavaScript 一样,在 DOM 树上找东西。我比较习惯用 jQuery,通过 CSS selector 来找页面上的节点非常舒服。

其实大部分的语言都有人实现了 HTML parser. 拿当下比较火的 Ruby 来说,随便一搜就找到两个:HpricotNokogiri.看名字好像都是日本人写的──不奇怪,Ruby 就是日本人发明的。

我在 Mac 上先试用了 Hpricot, 很奇怪我测试的一个文档不能正常处理。于是尝试 Nokogiri,很不错,没有发现问题。如果懂 XPath,Nokogiri 提供了 XPath 方式来寻找文档里的节点。或者你习惯了 CSS selector,在 Nokogiri 中也可以用类似 jQuery 的方法:

require 'nokogiri'

html = '...'
doc = Nokogiri::HTML(html)

# 获取页面上所有的链接
doc.css('a').each do |link|
  puts "#{link.content}, #{link['href']}"
end

# 打出 meta-keywords
puts doc.css('meta[name="keywords"'])[0].content

使用 Nokogiri 相对于正则表达式的优点当然是更简单直观,而且更安全。缺点呢?如果你只是要页面上很少的数据,Nokogiri 可能比正则表达式稍微慢点,因为不管你要的数据有多么少,它都需要分析整个 HTML 文档(不过 Nokogiri 也提供了 SAX 方式的解析)。

有意思的是 Nokogiri 一出来就号称比老牌的 Hpricot 快,然后 Hpricot 不服,很快就开始反击,我也不知道现在到底是什么情况了。有兴趣的可以看它们提供的 benchmark. 不过我想解析的速度再慢,这种过程的瓶颈还是在爬取网页这个环节上,尤其在中国这种网速超慢的条件下 :)

同分类推荐文章

  1. 等了十年的 Go 链式管道,终于来了:seq 让你像写 Scala 一样写 Go (2026-06-25 18:38:18)
  2. Go 实验特性详解 (2026-06-21 10:05:27)
  3. amd64 微架构级别对 Go 程序性能提升多少? (2026-06-21 09:38:49)

查看更多 后端 文章 →

建议继续学习

  1. 用Hyer来进行网站的抓取 (累计阅读 158,250)
  2. 每个程序员都应该学习使用Python或Ruby (累计阅读 17,917)
  3. 我的PHP,Python和Ruby之路 (累计阅读 13,146)
  4. 各公司对前端开发的职位描述 (累计阅读 10,405)
  5. 抓取网页内容生成Kindle电子书 (累计阅读 9,485)
  6. 浏览器的渲染原理简介 (累计阅读 8,377)
  7. iframe里src="about:blank"的问题。 (累计阅读 8,088)
  8. 程序员眼里IE浏览器是什么样的 (累计阅读 8,011)
  9. 2010网页设计趋势 (累计阅读 7,818)
  10. Web前端工程师编程能力飞升之路 (累计阅读 7,691)