Rubyを使ったプレイwright: 実践的なウェブスクレイピングチュートリアル
Lead Scraping Automation Engineer
TL;DR:
- Rubyは
playwright-ruby-clientを通じてPlaywrightを制御できます。 gemによって報告された正確に互換性のあるplaywright-coreバージョンをインストールします。 - 動的ページにはロケーターと明示的な待機を使用します。 チュートリアルでは、2つのJavaScriptレンダリングされたページを抽出し、構造化されたレコードを返します。
- すべての行に出所を保持します。 ページネーションエラーが追跡可能なままであるために、テキストと著者とともにソースURLを保存します。
- ブラウザを閉じ、ページネーションを制約します。 リソース制限や停止条件は、スクレイパーが定期ジョブになる前に重要です。
- ローカルPlaywrightには運用境界があります。 Scrapeless Scraping Browserは管理されたCDPエンドポイントを提供でき、Rubyは抽出ロジックを保持できます。
Playwrightは公式のRubyバインディングを公開していませんが、コミュニティによって維持されているplaywright-ruby-clientが、Playwrightプロトコルのための実用的なクライアントを提供します。これは、JavaScriptレンダリング、信頼できるロケーター、ブラウザナビゲーションを必要とするRubyアプリケーションにうまく機能します。
このチュートリアルでは、互換性のあるバージョンをインストールし、公開されたJavaScriptデモから2つのページをスクレイピングし、構造化データをエクスポートし、ローカルブラウザ操作がボトルネックになるときに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リポジトリは、ユーザーに対して、任意の最新パッケージをインストールするのではなく、gemに互換性のあるプロトコルバージョンを照会するよう指示します。
Install Playwright for Ruby
プロジェクトを作成し、gemを追加します:
ruby
# Gemfile
source 'https://rubygems.org'
gem 'playwright-ruby-client'
それをインストールし、互換性のあるPlaywrightバージョンを表示し、その正確なNodeパッケージをインストールします:
bash
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
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
bundle exec ruby scrape_quotes.rb
確認された実行は20件のレコードを返しました:最初のレコードはページ1から、最後のレコードはページ2から取得されました。これは、このサンプルでレンダリングされたセレクター、ページネーションのクリック、待機、および構造化された出力パスを証明します。これはスループットのベンチマークではありません。
Why the Script Uses Locators and Waits
動的ページの最初のHTMLにはレコードが含まれていない場合があります。page.gotoはドキュメントイベントを待機し、locator('.quote').first.wait_forはスクレイパーに必要なビジネス要素を待機します。
この区別は固定スリープを回避します。2秒の遅延は、1回の実行では必要以上に長く、別の実行では短すぎる可能性があります。ロケーターの待機は、実際の受け入れ条件を表現します。
ロケーターは、クエリを合成可能に保ちます。スクリプトは各.quoteを見つけ、その後、.textと.authorをその行内にスコープします。これにより、1つのカードの著者が別のカードのテキストとペアにならないようにします。
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、ページタイトル、必要なセレクター、および少なくとも1つのビジネス識別子を検証します。 HTTPセマンティクス仕様書は、レスポンスステータスを説明しますが、アプリケーションレベルのアイデンティティはスクレイパーの責任です。
Where Local Playwright Stops
ローカルのPlaywrightは、開発中にコードをシンプルに保ちます。生産環境では、チームは互換性のあるブラウザバイナリ、OS依存関係、プロセスクリーンアップ、メモリアロケーション、地理的ルーティング、セッションアイソレーション、および診断も維持します。
Rubyクライアントは、互換性のあるプロトコルを話すPlaywrightサーバーまたはCLIを必要とします。playwright-coreバージョンと一致しないgemをアップグレードすると、その境界が壊れる可能性があります。両方のパッケージを固定し、一緒に更新してください。
Scrapeless Scraping Browserは、ブラウザプロセスを管理されたサービスに移動します。Scrapelessは、そのSDKとCDP接続URLの両方をPlaywright統合ガイド内に文書化しています。
RubyをScrapelessブラウザセッションに接続する
前提条件: ライブクラウド接続には、ユーザー所有のScrapeless APIキーが必要です。ローカルのRubyスクレイピングスクリプトは正常に実行されましたが、この環境ではSCRAPELESS_API_KEYがなかったため、クラウドハンドシェイクが実行されませんでした。
文書化されたアーキテクチャは2つの側面を持っています:
- Scrapeless SDKまたは文書化されたブラウザエンドポイントを使用して管理されたScrapelessブラウザセッションを作成する。
- 結果として得られるWebSocketエンドポイントをRubyに渡し、クライアントサポートされたリモートブラウザメソッドを通じて接続する。
Rubyクライアントは、PlaywrightサーバーWebSocketのためのPlaywright.connect_to_browser_serverを文書化しています。ScrapelessはCDPエンドポイントを公開しているため、直接配線する前に現在のRubyクライアントのCDP互換性を確認してください。直接の互換性が不確かである場合は、ブラウザ境界に小さなNode接続サービスを維持し、構造化されたページ結果をRubyに送信します。一つのWebSocketプロトコルを別のものに静かに置き換えないでください。
その明示的な境界は、未検証の接続スニペットを公開するよりも安全です。それは、Rubyの抽出ロジックを確認しながら、セッションの作成とプロトコルの適応を、実際のアカウントで統合テストできるコンポーネントに残します。
結論
RubyとPlaywrightは、gemとplaywright-coreのバージョンが正確にペアリングされている場合に実用的です。ロケーター、ビジネスエレメントの待機、ページネーションの制限、由来、ブラウザのクリーンアップがデモを信頼できる出発点に変えます。
開発中はローカルChromeを使用してください。インストール、スケーリング、ルーティング、および診断が再発する運用の負担となる場合、ブラウザプロセスをScrapelessに移動し、展開前に実際の資格情報でリモートプロトコルの境界をテストします。
ブラウザ境界を一度構築する
Playwright Stealthガイドを読み、現在の価格を比較してから、Scrapelessアカウントを作成し、自分のAPIキーで管理されたセッションを確認してください。
FAQ
Q: PlaywrightはRubyを公式にサポートしていますか?
Microsoft Playwrightは公式のRubyバインディングを公開していません;playwright-ruby-clientはコミュニティが維持しているクライアントです。
Q: RubyはどのPlaywrightバージョンを使用する必要がありますか?
インストールしたgemからPlaywright::COMPATIBLE_PLAYWRIGHT_VERSIONを照会し、その正確なplaywright-coreバージョンをインストールします。
Q: Ruby PlaywrightでJavaScriptコンテンツを待機するにはどうすればよいですか?
固定のスリープに依存するのではなく、必要なビジネスコンテンツを表すロケーターを待機してください。
Q: ページネーションはどのように制限すべきですか?
最大ページ数を使用し、次のリンクが消えたら停止し、訪問したURLまたは記録キーを追跡します。
Q: RubyはScrapeless Scraping Browserに直接接続できますか?
ScrapelessはCDPエンドポイントを公開しており、RubyコミュニティクライアントはPlaywrightサーバー接続を文書化しています;実際のアカウントでプロトコルの互換性を確認するか、小さなテスト済みのNode境界を使用してください。
Scrapelessでは、適用される法律、規制、およびWebサイトのプライバシーポリシーを厳密に遵守しながら、公開されているデータのみにアクセスします。 このブログのコンテンツは、デモンストレーションのみを目的としており、違法または侵害の活動は含まれません。 このブログまたはサードパーティのリンクからの情報の使用に対するすべての責任を保証せず、放棄します。 スクレイピング活動に従事する前に、法律顧問に相談し、ターゲットウェブサイトの利用規約を確認するか、必要な許可を取得してください。



