ウェブスクレイピングにおけるScrapyとPuppeteerの比較

ウェブスクレイピングに人気の2つのツール、PuppeteerとScrapyについて学びましょう。
1 分読
Scrapy vs Puppeteer

要約

  • ScrapyはPythonフレームワークであり、ウェブスクレイピングにはクラスとパイプライン構造の知識が必要です。
  • Puppeteerは、ナビゲーションや要素操作機能を備えたNode.jsのヘッドレスブラウザツールです。
  • ScrapyはHTTPリクエストを介して数十ページを非同期で処理し、レイテンシは1秒未満です。
  • Puppeteerは全リソースをダウンロードしページ全体をレンダリングするため、処理が遅くリソースを大量に消費します。
  • Scrapyは大量の静的ページスクレイピングに優れるが、動的コンテンツにはミドルウェアが必要。
  • Puppeteerは動的サイト、ユーザー操作、JavaScriptレンダリング、スクリーンショット生成をネイティブに処理します。

ChatGPTやGeminiなどのAIアシスタントは、大規模言語モデル(LLM)が学習した膨大なコンテンツがなければ誕生しなかったでしょう。このコンテンツの多くはウェブスクレイピングによって取得されました。

ウェブスクレイピングはLLMの訓練に有用なだけでなく、市場分析、価格監視、リード生成にも活用できます。

本記事では、ウェブスクレイピングに広く使われる2つのツール、ScrapyとPuppeteerを比較します。Scrapyはウェブスクレイピングを目的に設計されたのに対し、Puppeteerはヘッドレスブラウザエミュレーションフレームワークです。ScrapyがPython向けに、PuppeteerがNode.js向けに開発された点は留意すべきですが、PuppeteerのPython移植版であるpyppeteerも利用可能です。

本記事では、各ツールの使いやすさ、スクレイピング速度、機能、コミュニティサポート、ユースケースを比較検討します。記事を読み終える頃には、どちらのツールがご自身に適しているか、より明確な判断材料が得られるでしょう。

Scrapy vs. Puppeteer: 使いやすさ

Scrapyは完全なフレームワークであり、利用開始前にクラスに関する知識が必要です。例えばScrapyの中核クラスであるスパイダーは、クロール対象ページとパース対象要素を定義します。他にもアイテム、セレクター、ItemLoaderなど多数のクラスが存在し、これら全てはパイプラインの概念内で活用するのが最適です。

ドキュメントは充実していますが、Scrapyを使用するにはコードの構造化方法に関する事前知識が必要です。

Scrapyのインストールとプロジェクト構造の作成には、ターミナルで以下のコマンドを実行します:

pip install scrapy
scrapy startproject <project_name>

一方、Puppeteerはヘッドレスブラウザを操作するための各種関数(ウェブサイトへの移動、要素の選択やクリックなど)を提供するだけです。コードを適切に構造化するのは開発者の責任となります。

Puppeteerの開始にはたった1つのコマンドで十分です。特定のプロジェクト構造を作成する必要はありません:

npm install puppeteer

一方、Puppeteerはヘッドレスブラウザを操作するための様々な関数を提供します:ウェブサイトへの移動、要素の選択やクリックなど。コードを適切に構造化するのは開発者の責任です。

Puppeteerの開始にはたった1つのコマンドで十分です。特定のプロジェクト構造を作成する必要はありません:

npm install puppeteer

Scrapy vs. Puppeteer: パフォーマンス

アプローチの違いから、ScrapyとPuppeteerはスクレイピング速度において大きく異なります。

ScrapyはサーバーにHTTPリクエストを送信し、その単一のリソース(主にHTML)に対するレスポンスを処理します。このアプローチにより、Scrapyは数十ページを非同期で処理し、DOMをトラバースし、必要な要素を選択することができ、そのすべてが1秒未満のレイテンシーで実行されます。

Puppeteerは全く異なるアプローチを取ります。ブラウザエミュレーションソフトウェアとして、ウェブサイトに移動し、すべてのリソース(画像や外部スクリプトなど)をダウンロードし、ブラウザのメモリに読み込みます。複数のヘッドレスブラウザを非同期で実行することは推奨されません。デバイスのパフォーマンスに大きな負荷をかけ、スクレイピング手順をさらに妨げる可能性があるためです。明らかに、Puppeteerは速度において優れていません。

Scrapy vs. Puppeteer: 機能比較

Scrapyには3つの注目すべき機能がある——Scrapyシェル、ミドルウェア、契約(Contracts)だ:

  • Scrapy shell
  • Scrapyはミドルウェアクラスを通じて様々なライブラリとの連携をサポートし、特定のユースケースに対応します。例えばChompjsはJavaScriptオブジェクトのパースに、Playwright for Pythonはスパイダー内で動的に読み込まれるコンテンツを持つウェブサイトのナビゲーションに使用できます。これらの機能はScrapyミドルウェアクラスを活用することで容易に統合可能です。
  • Scrapyスパイダーは契約(contract)で制約できます。契約とは、スパイダーが読み込んだページが期待通りであるかを判定する一種のテストです。例えば、ページの読み込み速度が十分か、必要な要素数が含まれているかをテストする契約を追加できます。カスタム契約の開発も可能です。

Scrapyはまた、アンチボット対策によるブロック回避のための豊富な機能を備えています。これにはプロキシサーバーとの連携や、ブラウザフィンガープリント(User-Agentなど)のローテーションが含まれます。

Puppeteerにはスクリーンショット生成、インタラクティブ操作、タイムライントレースといった独自機能も備わっています。完全なブラウザをエミュレートするため、ウェブページ全体をレンダリングします。これにより、レンダリングされたページをスクリーンショットやPDFに変換することが可能です。

Puppeteerは動的ウェブサイトのレンダリングに問題なく、それらと対話するための必要なツールを提供します。要素の選択、テキストの挿入、ボタンのクリックにより、Puppeteerはフォームの送信にも使用できます。これがPuppeteerを選択する主な理由の一つです(詳細は後述)。

Puppeteerはローテーションプロキシもサポートし、ブラウザパラメータを個別に調整することでブラウザフィンガープリントを操作できます。これらのパラメータを手動で調整するのが難しい場合、Puppeteerには「stealth」と呼ばれるプラグインがあり、作業を容易にします。

Puppeteerのもう一つの興味深い機能は、ウェブパフォーマンス監査を生成できる点です。これはウェブサイトテストに有用なだけでなく、ウェブサイトのサーバーがクローラーをスロットリングしているかどうかの特定にも利用できます:

Scrapy vs. Puppeteer: コミュニティサポート

2024年2月28日現在、ScrapyはGitHubで1,800人のウォッチャーと52,000のスターを獲得しており、ほぼ毎日様々なユーザーによるコミットが行われています。 ScrapyにはRedditコミュニティもあり、週に数件の質問が寄せられ、大半は6件程度の回答を得ています。さらにサポートが必要な場合は、ScrapyのDiscordコミュニティやStack Overflow(17,000件以上のScrapy関連質問が投稿済み)も利用可能です。

対照的に、GitHub上ではPuppeteerのウォッチャー数はScrapyより少ない(1,200)ものの、スター数は上回り(86,000)、様々な貢献者による毎日のコミットが行われています。PuppeteerはRedditやDiscordに公式サポートコミュニティを持ちませんが、Stack Overflowでは8,000件以上のPuppeteer関連質問が投稿されています。

最後に、PuppeteerとScrapyの両方とも、特定のユースケースに特化した豊富なコミュニティサポートのプラグインや拡張機能を備えています。例えば、Scrapyをヘッドレスブラウザと統合したり、動的ウェブサイトをパースしたりするためのものです。

ScrapyとPuppeteerのユースケース

これまで、この記事では2つのユースケースについて簡単に学び、両ツールがそれぞれ得意とする領域(大量の静的データのスクレイピングと動的に読み込まれるデータへのアクセス)について理解しました。

静的ウェブページの大規模ウェブスクレイピング

Scrapyは対象ページのDOMを単純に読み込むため、数千ページに分散したデータの大規模スクレイピングプロジェクトに最適です。非同期動作が可能で追加リソースをダウンロードしないため、複数のウェブサイトを同時に訪問でき、数十のウェブサイトを1秒未満のレイテンシーで容易にスクレイピングできます。 例えば、お気に入りのニュースサイトの全記事コメント欄からコメントを全てダウンロードしたい場合、Scrapyが優れています。

対照的に、Puppeteerで同じことを行おうとすると、個々のページだけをブラウザで完全に読み込むことはできません。ウェブアプリケーションのテスト用に設計されたツールとして当然のことながら、ウェブサイトを完全にレンダリングするために追加の画像、スクリプト、その他の埋め込みオブジェクトもダウンロードします。これにより、ページのリストが静的コンテンツのみで構成されている場合には不要なオーバーヘッドが発生し、Scrapyを使用する場合よりもはるかに遅くなります。

動的ウェブページからのコンテンツスクレイピング

今日のウェブは、単に情報をページ上に表示するだけでなく、双方向性を重視しています。多くのウェブサイトがグラフィカルユーザーインターフェース(GUI)化しており、以下のようなシナリオが発生します:

  • コメントは「コメントを読む」ボタンで非表示になっており、クリックするとページに追加される。
  • コンテンツがタブ内にグループ化されている。
  • 記事がペイウォールの後ろに隠されており、ログインとCAPTCHAの送信が必要。
  • 単一ページで構成され、ユーザーの閲覧行動によってコンテンツが決定されるウェブサイトが存在します。

Scrapyはデフォルトではこの種のコンテンツを処理できません。動的ウェブサイトのスクレイピングには、Splashのようなミドルウェアとの連携、またはPlaywrightやSeleniumのようなブラウザエミュレーションツールの使用が必要です。

このユースケースにおいて、PuppeteerはScrapyを圧倒的に凌駕します。ヘッドレスブラウザのパラダイムによりウェブページを完全に読み込み、JavaScriptコードがウェブサイトのインタラクティブ性を実現します。まだ読み込まれていない特定のHTML要素にアクセスしようとする代わりに、Puppeteerはウェブアプリケーションと対話し、HTML要素の読み込みを待機(存在確認のポーリングを含む)、それらを選択し、利用可能になった時点でコンテンツをダウンロードできます。

重要な点として、ScrapyとPuppeteerはscrapy-pyppeteerモジュールを使用して連携可能です。Scrapyのフレームワークを信頼しつつ、動的に読み込まれるコンテンツにアクセスするためのヘッドレスブラウザが必要な場合に、このモジュールが役立つでしょう。

結論

ScrapyとPuppeteerは、全く異なるパラダイムに従い、異なる目的を念頭に設計されたツールです。しかし、どちらもウェブコンテンツのウェブスクレイピングに使用できます。このアプローチの違いにより、Scrapyは膨大な量のデータをスクレイピングするための最適なソリューションであり、Puppeteerは特定のユーザー操作後にコンテンツをレンダリングするウェブサイトのナビゲーションに最適な選択肢です。

ただし共通点も存在します。コミュニティの規模はほぼ同等であり、使いやすさにおいてもほぼ互角です。ブラウザフィンガープリントやプロキシローテーションといった共通機能も備えています。

スクレイピング作業を工業化するためのツールスタックをお探しなら、Bright Dataをご検討ください。数百万のプロキシサーバー、スクレイピングAPI、スクレイピングブラウザ、すぐに利用可能なデータセットを提供しています。Bright Dataには優れたウェブスクレイピングのドキュメントも多数用意されています。例えば、Puppeteerによるウェブスクレイピングの詳細を学んだり、PuppeteerとScrapyの両方との統合を探索したりできます。

次に、PuppeteerとSeleniumを比較してみましょう