返回博客

使用 Ruby 的 Playwright:实用的网页抓取教程

Daniel Kim
Daniel Kim

Lead Scraping Automation Engineer

13-Aug-2026

TL;DR:

  • Ruby 可以通过 playwright-ruby-client 控制 Playwright。 安装 gem 报告的完全兼容的 playwright-core 版本。
  • 对于动态页面使用定位器和显式等待。 本教程提取两个由 JavaScript 渲染的页面并返回结构化记录。
  • 保持每一行的出处。 与文本和作者一起存储源 URL,以便分页错误保持可追溯。
  • 关闭浏览器和限制分页。 在爬虫变成定时任务之前,资源限制和停止条件非常重要。
  • 本地 Playwright 有操作边界。 Scrapeless Scraping Browser 可以提供一个托管的 CDP 端点,而 Ruby 保持提取逻辑。

Playwright 并没有发布官方的 Ruby 绑定,但社区维护的 playwright-ruby-client 提供了一个实用的 Playwright 协议客户端。它非常适合需要 JavaScript 渲染、可靠定位器和浏览器导航的 Ruby 应用,而不需要将整个项目迁移到 Node.js。

本教程安装兼容版本,从一个公共 JavaScript 演示中抓取两个页面,导出结构化数据,并解释如何在本地浏览器操作成为瓶颈时将浏览器进程转移到 Scrapeless。

Prerequisites

您需要 Ruby、Bundler、Node.js 和一个安装的基于 Chromium 的浏览器。经验证的运行使用 Ruby 2.6.10、playwright-ruby-client 1.62.0、playwright-core 1.62.1 和 Google Chrome。

确切的 Playwright Core 版本非常重要。playwright-ruby-client repository 指示用户查询 gem 以获取其兼容的协议版本,而不是安装任意最新的软件包。

Install Playwright for Ruby

创建一个项目并添加 gem:

ruby Copy
# Gemfile
source 'https://rubygems.org'

gem 'playwright-ruby-client'

安装它,打印兼容的 Playwright 版本,然后安装那个确切的 Node 包:

bash Copy
bundle install
PLAYWRIGHT_CLI_VERSION=$(bundle exec ruby -e 'require "playwright/version"; puts Playwright::COMPATIBLE_PLAYWRIGHT_VERSION')
npm install "playwright-core@$PLAYWRIGHT_CLI_VERSION"

如果没有可用的本地浏览器,./node_modules/.bin/playwright-core install chromium 会下载兼容的 Chromium 构建。下面的示例则指向一个现有的 Chrome 可执行文件。

社区客户端的 文档网站 涉及支持的浏览器 API。公共的 JavaScript quotes demo 是这里使用的目标。

Scrape a Dynamic Page With Ruby

创建 scrape_quotes.rb

ruby Copy
require 'json'
require 'playwright'

chrome = '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome'
cli = './node_modules/.bin/playwright-core'
rows = []

Playwright.create(playwright_cli_executable_path: cli) do |playwright|
  playwright.chromium.launch(headless: true, executablePath: chrome) do |browser|
    page = browser.new_page
    page.goto('https://quotes.toscrape.com/js/page/1/', waitUntil: 'domcontentloaded')

    2.times do
      page.locator('.quote').first.wait_for

      page.locator('.quote').all.each do |quote|
        rows << {
          text: quote.locator('.text').text_content,
          author: quote.locator('.author').text_content,
          source_url: page.url
        }
      end

      next_link = page.locator('li.next a')
      break if next_link.count.zero?

      next_link.click
      page.locator('.quote').first.wait_for
    end
  end
end

puts JSON.pretty_generate({ count: rows.length, first: rows.first, last: rows.last })

运行它:

bash Copy
bundle exec ruby scrape_quotes.rb

经验证的运行返回了 20 条记录:第一条记录来自第 1 页,最后一条来自第 2 页。这证明了渲染的选择器、分页点击、等待和结构化输出路径在这个示例中的作用。这不是一个吞吐量基准。

Why the Script Uses Locators and Waits

动态页面上的初始 HTML 可能不包含记录。page.goto 等待文档事件,而 locator('.quote').first.wait_for 等待爬虫所需的业务元素。

这种区别避免了固定的睡眠。两秒的延迟在某次运行中可能比必要的时间长,而在另一次中又可能太短。定位器等待表达了实际的接受条件。

定位器还让查询可组合。脚本找到每个 .quote,然后在该行内作用于 .text.author。这防止了一个卡片的作者与另一个的文本配对。

Add Safe Pagination and Structured Output

每个分页循环需要一个停止条件。本教程使用 2.times,然后如果没有下一个链接则提前退出。生产作业可以将页面限制与已访问 URL 集合和记录去重键结合起来。

在每个记录中保持 source_url。当选择器发生变化或出现重复时,出处使得能够重现页面并区分解析器错误与源更改。

对于文件输出,将最后的 puts 替换为 File.write('quotes.json', JSON.pretty_generate(rows))。写入临时文件,并在验证后仅在下游读取者可能同时消费输出时重命名。

Control Browser Resources

launch 的块形式在块结束时关闭浏览器,包括大多数异常。定时作业还应限制:

  • 最大页面和导航深度;
  • 同时的浏览器上下文;
  • 导航和定位器超时;
  • 截图和跟踪保留;
  • 接受的响应类型和最大负载大小。

返回状态 200 的页面仍然可能是错误的表示。在保存记录之前,验证最终 URL、页面标题、所需选择器和至少一个业务标识符。HTTP 语义规范 解释了响应状态,但应用级身份仍然是爬虫的责任。

Where Local Playwright Stops

本地 Playwright 在开发期间保持代码简单。在生产中,团队还维护兼容的浏览器二进制文件、操作系统依赖项、进程清理、内存分配、地理路由、会话隔离和诊断。

Ruby 客户端需要一个能够使用兼容协议的 Playwright 服务器或 CLI。升级该 gem 而不匹配其 playwright-core 版本可能会破坏该边界。将两个包固定并一起更新。

Scrapeless Scraping Browser 将浏览器进程移动到托管服务。Scrapeless 在 Playwright 集成指南 中记录了其 SDK 和 CDP 连接 URL。

将 Ruby 连接到 Scrapeless 浏览器会话

前提条件: 活跃的云连接需要一个由用户拥有的 Scrapeless API 密钥。本地 Ruby 抓取脚本成功运行;由于没有可用的 SCRAPELESS_API_KEY,因此未在此环境中执行云握手。

所述架构有两部分:

  1. 使用 Scrapeless SDK 或文档化的浏览器端点创建一个托管的 Scrapeless 浏览器会话;
  2. 将结果 WebSocket 端点提供给 Ruby,并通过客户端支持的远程浏览器方法进行连接。

Ruby 客户端记录了 Playwright.connect_to_browser_server 作为 Playwright 服务器 WebSocket。Scrapeless 暴露了一个 CDP 端点,因此在直接连接之前,请确认当前 Ruby 客户端的 CDP 兼容性。当不确定直接兼容性时,请在浏览器边界保留一个小的 Node 连接服务,并将结构化的页面结果发送到 Ruby。不要在不知不觉中用一个 WebSocket 协议替代另一个。

这种明确的边界比发布未经测试的连接代码片段更安全。它保留了经过验证的 Ruby 提取逻辑,同时将会话创建和协议适配留在可以用真实账户进行集成测试的组件中。

结论

当 gem 和 playwright-core 版本完全匹配时,使用 Ruby 的 Playwright 是实用的。定位器、业务元素等待、边界分页、来源和浏览器清理将演示变成可靠的起点。

在开发时使用本地 Chrome。在安装、扩展、路由和诊断成为重复的操作负担时,将浏览器进程移到 Scrapeless,并在部署之前使用真实凭据测试远程协议边界。


一次构建浏览器边界

阅读 Playwright Stealth 指南,比较 当前定价,然后创建一个 Scrapeless 账户,并使用自己的 API 密钥验证托管会话。


常见问题

问:Playwright 官方支持 Ruby 吗?

Microsoft Playwright 不发布官方的 Ruby 绑定;playwright-ruby-client 是一个社区维护的客户端。

问:Ruby 应该使用哪个 Playwright 版本?

查询已安装 gem 的 Playwright::COMPATIBLE_PLAYWRIGHT_VERSION 并安装该确切的 playwright-core 版本。

问:如何在 Ruby Playwright 中等待 JavaScript 内容?

等待表示所需业务内容的定位器,而不是依赖固定的睡眠。

问:分页应该如何界定?

使用最大页面计数,当下一个链接消失时停止,并跟踪访问过的 URL 或记录键。

问:Ruby 能否直接连接到 Scrapeless Scraping Browser?

Scrapeless 暴露了一个 CDP 端点,而 Ruby 社区客户端记录了一个 Playwright 服务器连接;使用真实账户验证协议兼容性,或使用一个小的经过测试的 Node 边界。

在Scrapeless,我们仅访问公开可用的数据,并严格遵循适用的法律、法规和网站隐私政策。本博客中的内容仅供演示之用,不涉及任何非法或侵权活动。我们对使用本博客或第三方链接中的信息不做任何保证,并免除所有责任。在进行任何抓取活动之前,请咨询您的法律顾问,并审查目标网站的服务条款或获取必要的许可。

最受欢迎的文章

目录