返回博客
指南
Raluca PenciucLast updated on Mar 31, 20263 min read

HTML 和 XML 解析 Ruby 库终极指南

HTML 和 XML 解析 Ruby 库终极指南

网络爬虫(即从网络中提取数据)涉及读取和处理 HTML 及 XML 文档中的内容。为了简化这一任务,开发人员会使用名为“解析器”的专用库。

在 Ruby HTML 解析器方面,Ruby 社区提供了多种选择,而为您的项目选择合适的解析器可能是一项艰巨的任务。为了帮助您做出明智的决定,以下是在选择解析器时需要考虑的几个关键因素:

  • 是否为开源且可免费使用。
  • 对不同 HTML 和 XML 标准的支持程度。
  • 是否提供详尽的文档和教程,以帮助开发者快速入门。
  • 能够处理不同类型的编码,特别是在处理非拉丁语系语言时。
  • 拥有轻量且易于使用的 API,便于浏览和搜索 HTML 及 XML 文档。
  • 该库提供的错误处理和验证能力。
  • 拥有一个强大且活跃的社区,提供支持与资源。
  • 库的大小及其内存占用。
  • 性能良好,特别是在处理大文件时。
  • 如果处理使用 XML 命名空间的文档,则需支持 XML 命名空间。
  • 是否得到积极维护,以确保与最新版本的 Ruby 兼容并获得错误修复。
  • 库提供的可扩展性或自定义选项的丰富程度。

本文将深入探讨六款流行的 Ruby HTML 和 XML 解析库,并根据上述标准对其进行评估,以帮助您找到满足网页抓取需求的理想工具。

Nokogiri

Nokogiri 是一款在 Ruby 中用于解析和搜索 XML 及 HTML 文档的流行且功能强大的库。它拥有简洁明了的 API,并基于 libxml2 构建,后者是一个成熟的用于解析 XML 的 C 语言库。

Gem 命令

gem install nokogiri

代码示例

require "nokogiri"

html = "<!DOCTYPE html><html><head><title>Hello, World!</title></head><body>Hello, World!</body></html>"

parsed_data = Nokogiri::HTML.parse(html)

puts parsed_data.title

优缺点

以下是使用 Nokogiri 的一些优缺点:

优点

  • 它被广泛认为是 Ruby 最受欢迎、使用最广泛的解析器
  • 它运行速度极快且高效,得益于其采用 libxml2 作为解析引擎,能够轻松处理大型文档。
  • 它拥有简单且用户友好的 API,便于在 XML 和 HTML 文档中进行导航和搜索。
  • 它同时支持 XML 和 HTML 文档,因此您可以使用同一个库来解析不同类型的文档。
  • 它提供了一套丰富的函数用于搜索和操作文档中的元素,使提取所需信息变得轻松。您可以使用 CSS 选择器或 XPath 提取数据。
  • 它能够解析格式错误的 HTML 文档
  • 它兼容不同的 Ruby 版本,并且正在积极维护中
  • 它还同时支持 SAX(XML 简单 API)和 DOM(文档对象模型)解析器

缺点

  • 某些解析任务可能需要对 DOM 结构有深入的理解,如果开发者不熟悉它,可能会难以掌握。
  • 与 Ox 等其他库相比,它可能需要更多的内存。
  • 它可能难以解析受身份验证保护的文档,例如需要用户名和密码才能访问的网站。
  • 它不支持多线程,因此如果您计划在多线程环境中使用它,则需要格外小心。
  • 它不适合通过 JavaScript(例如 AJAX)传递包含动态加载内容的文档。

Ox

Ox(即 Optimized XML)是一个功能强大且高效的库,用于在 Ruby 中解析和操作 XML 及 JSON 文档。

该库采用 C 语言实现,以获得更好的性能和内存效率。Ox 使用拉式解析器来解析文档,这使其能够以比基于 DOM 的解析器更少的内存占用来解析大文件。

Ox 处理 XML 文档的一些方式包括:

  • 作为通用的 XML 解析器和写入器:Ox 可以读写 XML 文档,并提供用于搜索和操作文档中元素的方法。
  • 作为快速的对象/XML 序列化器:Ox 能够将 XML 文档转换为 Ruby 对象,反之亦然。此功能便于进行数据的序列化和反序列化。
  • 作为流式 SAX 解析器:Ox 能够以流式方式解析 XML,这适用于大型文件,并提供了一种处理 XML 事件的快速方法。

Gem 命令

gem install ox

代码示例

require "ox"

doc = Ox.parse(%{

  <?xml version="1.0"?>

  <Payment>

	<Shop>ikea</Shop>

	<Amount>199.99</Amount>

	<Date>2023-01-12</Date>

  </Payment>

})

puts doc.Payment.Shop.text

优缺点

以下是使用 Ox 的优缺点:

优点

  • 得益于其采用的拉取式解析器(pull-parser)方法以及使用 C 语言实现,Ox 运行速度极快且内存利用率极高。这使其非常适合解析大型 XML 和 JSON 文档,或处理流式数据
  • Ox 拥有简洁明了的 API,易于使用和理解
  • Ox 同时支持 JSON 和 XML,因此您可以使用同一个库来解析不同类型的文档
  • 它内置了对 XML 命名空间的支持,这使得处理包含命名空间的 XML 文档变得更加容易。
  • 它正被积极维护和更新

缺点

  • 与 Nokogiri 或 REXML 等其他库相比,其用于搜索和操作元素的 API 可能功能稍显单薄
  • 其社区和支持可能不如 Nokogiri 等更成熟的库那样强大

Oga

Oga 是一个用于在 Ruby 中解析和搜索 XML 及 HTML 文档的现代轻量级库。与其他库相比,它采用了一种更现代的方法,即使用纯 Ruby 实现,这意味着它不依赖任何 C 库。

该库适用于中小型文档,且不需要 XSLT 或 XML 模式验证等高级功能。

尽管该库不需要 libxml 等系统库,但为了获得更好的性能,Oga 使用了一个小型原生扩展(MRI/Rubinius 版为 C 语言,JRuby 版为 Java)。

Gem 命令

gem install oga

代码示例

require "oga"

doc = Oga.parse_xml(%{

  <?xml version="1.0"?>

  <Payment>

	<Shop>ikea</Shop>

	<Amount>199.99</Amount>

	<Date>2023-01-12</Date>

  </Payment>

})

puts doc.at_xpath("Payment/Shop/text()")

优缺点

以下是使用 Oga 的一些优缺点:

优点

  • Oga 拥有简洁明了的 API,便于浏览和搜索 XML 及 HTML 文档。
  • 纯 Ruby 实现使其易于在不同平台和环境中安装和运行。
  • Oga 的 API 支持在多线程环境中安全地解析和查询文档,无需担心性能问题
  • Oga 轻量级,易于与其他库和模块集成。
  • Oga 的内存占用率很低。

缺点

  • Oga 不支持 XPath、XSLT 或根据 DTD 或 XML 架构对 XML 文档进行验证等高级功能。
  • 与 Nokogiri 等其他库相比,Oga 的功能较为有限,可能不适合复杂的 XML 或 HTML 解析任务。
  • 尽管它仍在维护中,但与 Nokogiri 相比,其更新频率较低

LibXML Ruby

LibXML Ruby 是 libxml2 C 库的绑定,libxml2 是一个用于解析和操作 XML 文档的成熟库。该绑定为 libxml2 的功能提供了一个接口,并被包括 Nokogiri 在内的其他几个流行的库所使用。

该库具备 XPath 支持、DTD 解析、XSL 转换等高级功能。

Gem 命令

gem install libxml-ruby

代码示例

require "xml"

doc = XML::Parser.string(%{

  <?xml version="1.0"?>

  <Payment>

	<Shop>ikea</Shop>

	<Amount>199.99</Amount>

	<Date>2023-01-12</Date>

  </Payment>

})

puts doc.parse.find('//Shop').first.content

优缺点

以下是其优缺点列表:

优点

  • 得益于其底层的 C 库,该库为在 Ruby 中解析和处理 XML 及 HTML 文档提供了快速高效的方式。
  • 它支持多种编码类型,并能处理具有复杂结构和命名空间的文档
  • 支持 XPath,这是一种允许您根据元素的属性和关系在 XML 文档中导航并选择元素的语言。
  • 支持 XSLT 转换以及 DTD/XML 模式验证
  • 拥有广泛的功能和选项,使其适合高级用例。
  • 它得到了社区的大力支持,是一个稳定且文档完善的库。

缺点

  • 它比某些纯 Ruby 实现的库消耗更多的内存
  • 其 API 不如其他一些用于解析 XML 的 Ruby 库那样直观或用户友好,这可能会让经验较少的开发者在使用时感到困难
  • 它不原生支持 JSON 解析,处理 JSON 需要额外的配置和工具
  • 它处理格式错误的 XML 的能力可能不如其他一些库。

REXML

REXML 是一个用于解析 XML 文档的纯 Ruby 库,它包含在标准 Ruby 库中,因此易于使用,无需额外安装。

它受 Java 的 Electric XML 库启发,具有易于使用的 API、体积小和速度快的特点。

Gem 命令

gem install rexml

代码示例

require "rexml/document"

doc = REXML::Document.new(%{

  <?xml version="1.0"?>

  <Payment>

	<Shop>ikea</Shop>

	<Amount>199.99</Amount>

	<Date>2023-01-12</Date>

  </Payment>

})

doc.elements.each("//Shop"){ |element| puts element.text }

优缺点

优点

  • 它包含在标准 Ruby 库中,因此易于安装和使用。
  • REXML 是纯 Ruby 实现,这意味着它不依赖任何 C 库或外部依赖项,因此具有平台独立性。
  • 它拥有简单易用的 API,因此是处理中小型 XML 文档的理想选择
  • 内置了 XPath 实现,便于在 XML 文档中搜索和选择元素

缺点

  • REXML 的速度不如 Nokogiri 等其他库,并且会消耗更多的内存,因此不太适合处理大型 XML 文档。
  • 它缺乏其他 XML 库的一些高级功能,例如处理 XML 命名空间或高级错误处理

Selenium WebDriver

Selenium WebDriver 主要不是一个 HTML 或 XML 解析器,而是一个浏览器自动化工具。它允许您通过编程方式与 Web 浏览器交互,模拟用户操作,例如点击按钮、填写表单以及在页面之间导航。

Selenium WebDriver 允许您自动化与网页浏览器的交互,例如点击按钮、填写表单以及在页面之间导航。

当您需要抓取使用 JavaScript 动态加载内容的网站,或执行与页面表单或按钮交互等特定操作时,该工具非常有用。

Gem 命令

gem install selenium-webdriver webdrivers

代码示例

require "selenium-webdriver"

require "webdrivers/chromedriver"

driver = Selenium::WebDriver.for :chrome

driver.get("https://webscrapingapi.com")

puts driver.title

优缺点

以下是使用 Ruby 中的 Selenium WebDriver 的一些优缺点:

优点

  • Selenium WebDriver 支持多种网页浏览器,包括 Chrome、Firefox、Edge、Safari 等,这意味着您创建的测试无需修改即可在不同浏览器上运行。
  • Selenium WebDriver 提供了多种检查网页内容的方法,例如通过 ID、类名或 CSS 选择器定位元素,这使得与网页交互并自动化任务变得非常容易。
  • 它允许您与网页上的 JavaScript 元素进行交互,这一特性使其非常适合测试包含 JavaScript 的网页行为。
  • 它在业界被广泛使用,文档完善,并且拥有庞大的开发者社区可以提供支持。

缺点

  • Selenium WebDriver 可能比其他 HTML 解析库运行得更慢,因为它需要启动浏览器并模拟真实用户的交互,这可能会增加抓取数据所需的时间。
  • Selenium WebDriver 依赖于计算机上已安装的 Web 浏览器,这会在无头环境或没有 GUI 的服务器上运行脚本时造成问题。
  • Selenium WebDriver 并非专用的 HTML 解析库,其 API 可能不如 Nokogiri 或

值得一提

虽然我们主要关注了 Ruby 中用于解析 HTML 和 XML 的活跃且维护良好的库,但还有其他一些库也值得考虑。

但是,需要注意的是,这些库可能维护不那么积极,或者社区支持较少,如果在生产环境中使用,可能会增加额外的风险。

在做出决定之前,务必仔细评估库的功能和性能,以及需要解析的文档的大小和复杂度。

Hpricot

Hpricot 是另一款流行的 Ruby HTML 解析器,同时支持 XML 文档。Hpricot 拥有简单易用的 API,非常适合处理中小型文档。

Gem 命令

gem install hpricot

代码示例

require "hpricot"

doc = "<!DOCTYPE html><html><head><title>Hello, World!</title></head><body>Hello, World!</body></html>"

puts Hpricot(doc).at("title").inner_html

优缺点

以下是使用 Hpricot 的优缺点:

优点

  • Hpricot 拥有简单易用的 API,便于浏览和搜索 HTML 及 XML 文档。
  • Hpricot 的搜索功能基于类似 jQuery 的 CSS 选择器,易于理解和使用。
  • 由于 Hpricot 的部分代码采用 C 语言编写,因此该库运行相对快速且高效
  • 它适用于中小型文档
  • 与 Nokogiri 一样,它能够解析格式不规范的文档

缺点

  • Hpricot 自 2010 年以来就未再积极维护,因此可能无法与 Ruby 的最新版本良好兼容,并且可能缺乏对新功能的支持和错误修复。
  • Hpricot 的搜索功能并不支持所有的 CSS 选择器,也不支持 XML 命名空间。
  • 它无法处理格式错误的 XML 文档
  • 与 Nokogiri 或 Ox 等其他库相比,Hpricot 的性能可能较慢,且内存消耗更大,特别是在处理较大文档时。

结论

总而言之,在 Ruby 中解析 HTML 和 XML 文档时,有多种库可供选择,每种都有其优缺点。

Nokogiri、REXML、Ox、Hpricot 和 LibXML Ruby 都是可用于网络爬虫的强大库,但在决定使用哪一个之前,评估项目的具体要求和需求非常重要。

Selenium WebDriver 虽然主要并非为 HTML 解析而设计,但也适用于网络爬虫,但作为一款浏览器自动化工具,与专业库相比,它会带来一些额外的复杂性,且性能较慢。

然而,编写网页抓取脚本可能是一项耗时且困难的任务,特别是当您需要处理动态网站、验证码(CAPTCHA)以及应对封禁时。

WebScrapingAPI 提供了一种简单而有效的解决方案,可直接从网络获取数据,省去了编写脚本的麻烦。通过使用“提取规则”功能,您只需指定元素的 CSS 选择器,即可轻松从网页中提取信息。

何不立即注册一个账户呢?

关于作者
Raluca Penciuc, 全栈开发工程师 @ WebScrapingAPI
Raluca Penciuc全栈开发工程师

Raluca Penciuc 是 WebScrapingAPI 的全栈开发工程师,主要负责开发爬虫、优化规避机制,并探索可靠的方法以降低在目标网站上的被检测概率。

开始构建

准备好扩展您的数据收集规模了吗?

加入2,000多家企业,使用WebScrapingAPI在无需任何基础设施开销的情况下,以企业级规模提取网络数据。