Puppeteerをオンラインで実行するための最良の方法:ソリューション比較
Takashi Yamamoto
Infrastructure Engineer · Leapcell

「Puppeteer」という言葉を聞いたことがない人はいますか? これは、人間によるWebページへの操作をシミュレートして、さまざまな複雑な要件を実現できる強力なブラウザ自動化ツールです。例えば、ウェブサイトのスクリーンショットの取得、PDFの生成、自動テスト、ウェブサイトのスクレイピング、Webコンテンツの変更の監視などです。
多くの場合、Puppeteerをオンラインで実行する必要があります。例えば:
- CI/CDパイプラインで、オンラインのPuppeteerを呼び出して自動テストを実行する。
- cronを使用してウェブサイトの利用可能性を定期的にチェックする。
- 大規模な分散型Webクローラーを実行する。
Puppeteerタスクは通常短命で、継続的にトリガーされるわけではないため、フルサーバー(DigitalOceanなど)にホストすると、Puppeteerが実行されているかどうかにかかわらず、サーバーが常に課金されるため、費用対効果が悪くなります。
理想的なアプローチは、サーバーレスモデルを使用してPuppeteerをデプロイすることです。サーバーレスサービスは実際のアクティブ化に基づいて課金されるため、さまざまなシナリオで通常はるかに安価です。
現在、Puppeteerをサーバーレス方式で実行できるプラットフォームはごくわずかです。Leapcell、AWS Lambda、そしてCloudflare Browser Renderingです。
この記事では、これらのプラットフォームについて、典型的なPuppeteerタスクを完了するためにどのように使用するか、そしてそれぞれの長所と短所を探ります。
タスク
例として、一般的なPuppeteerのユースケースであるWebページのスクリーンショットキャプチャを使用します。
タスクは次の手順を伴います:
- 指定されたURLにアクセスする
- ページのスナップショットを取る
- 画像を返す
Leapcell
コード例:
const puppeteer = require('puppeteer'); const { Hono } = require('hono'); const { serve } = require('@hono/node-server'); const screenshot = async (url) => { const browser = await puppeteer.launch({ args: ['--single-process', '--no-sandbox'] }); const page = await browser.newPage(); await page.goto(url); const img = await page.screenshot(); await browser.close(); return img; }; const app = new Hono(); app.get('/', async (c) => { const url = c.req.query('url'); if (url) { const img = await screenshot(url); return c.body(img, { headers: { 'Content-Type': 'image/png' } }); } else { return c.text('Please add a ?url=https://example.com/ parameter'); } }); const port = 8080; serve({ fetch: app.fetch, port }).on('listening', () => { console.log(`Server is running on port ${port}`); });
Leapcellはさまざまな言語でのデプロイをサポートしているため、この要件は容易に満たされます。
ローカル開発とデバッグ
ローカルデバッグは非常に簡単です。他のNode.jsアプリケーションと同様に、node index.js
を実行するだけで完了です!
デプロイ
デプロイには、ビルドコマンド、実行コマンド、およびサービスポートを指定する必要があります(下のスクリーンショットに示すように)。
具体的なデプロイパラメータと手順については、公式ドキュメントで詳細を確認してください。
デプロイ後、アプリケーションはオンラインで利用可能になります。
まとめ
✅ 長所:
- 一貫したローカル環境とクラウド環境により、デバッグが容易になります。
- 公式Puppeteerライブラリをサポートしています。
❌ 短所:
- セットアップが若干複雑:独自のHTTPハンドラーを記述する必要があります。
AWS Lambda
コード例:
const chromium = require('chrome-aws-lambda'); exports.handler = async (event) => { let browser = null; try { browser = await chromium.puppeteer.launch({ args: chromium.args, defaultViewport: chromium.defaultViewport, executablePath: await chromium.executablePath, headless: chromium.headless, }); const page = await browser.newPage(); await page.goto(event.url); const screenshot = await page.screenshot(); return { statusCode: 200, headers: { 'Content-Type': 'image/jpeg' }, body: screenshot.toString('base64'), isBase64Encoded: true, }; } catch (error) { return { statusCode: 500, body: 'Failed to capture screenshot.', }; } finally { if (browser !== null) { await browser.close(); } } };
AWS Lambdaは、puppeteer-core
と、alixaxel/chrome-aws-lambdaのようなサードパーティのChromiumライブラリを使用する必要があります。
これは、AWSがLambda関数のサイズに250MBの制限を設けているためです。PuppeteerにバンドルされているChromiumは、この制限を簡単に超える可能性があります(macOSで約170MB、Linuxで282MB、Windowsで280MB)。そのため、小規模版のChromiumを使用する必要があります。
ローカル開発とデバッグ
alixaxel/chrome-aws-lambdaのドキュメントで見られるように、ランタイム環境の違いにより、ローカルデバッグには複雑な設定が必要です。
デプロイ
デプロイするには、node_modules
をZIPファイルとしてアップロードする必要があります。ユースケースによっては、Lambda Layersの構成も必要になる場合があります。主なビジネスロジックはAWSコンソールで直接記述でき、保存後に実行できます。
まとめ
✅ 長所:
- 実装コードは比較的シンプルです。
❌ 短所:
- サードパーティのChromiumライブラリに依存しており、潜在的なリスクをもたらす可能性があります。
- ローカルデバッグが複雑です。
- デプロイプロセスが煩雑で、ZIPファイルのパッケージ化とアップロード、そして場合によってはLambda Layersの構成が必要です。
Cloudflare Browser Rendering
コード例:
import puppeteer from '@cloudflare/puppeteer'; export default { async fetch(request, env) { const { searchParams } = new URL(request.url); let url = searchParams.get('url'); if (url) { url = new URL(url).toString(); // normalize const browser = await puppeteer.launch(env.MYBROWSER); const page = await browser.newPage(); await page.goto(url); const img = await page.screenshot(); await browser.close(); return new Response(img, { headers: { 'content-type': 'image/png', }, }); } else { return new Response('Please add a ?url=https://example.com/ parameter'); } }, };
Cloudflare Browser Renderingは、比較的新しいサーバーレスPuppeteerソリューションです。AWS Lambdaと同様に、公式Puppeteerライブラリはサポートしていません。代わりに、Cloudflareが提供するPuppeteerのバージョンを使用します。
Cloudflareのライブラリは、どのサードパーティ製オプションよりも安全ですが、更新サイクルが遅いことはフラストレーションの原因になることがあります。例えば、かつては5ヶ月以上更新されないこともありました。
さらに、Cloudflare Browser Renderingにはいくつかの制限があります:
- Worker Proユーザーのみ利用可能です。
- 各Cloudflareアカウントは、1分あたり最大2つのブラウザを作成でき、同時に実行できるブラウザは最大2つまでです。
ローカル開発とデバッグ
ローカルデバッグには、複雑な設定が必要です。
デプロイ
デプロイするには、オンラインで関数を記述し、保存して実行するだけです。
まとめ
✅ 長所:
- 実装コードは比較的シンプルです。
❌ 短所:
- CloudflareのPuppeteerライブラリに依存しており、更新サイクルが不安定です。
- ローカルデバッグが複雑です。
- 従量課金制とその他の制限があり、柔軟な使用が妨げられます。
結論
この記事では、Puppeteerをオンラインでデプロイするための3つの主要なサーバーレスプラットフォーム、Leapcell、AWS Lambda、Cloudflare Browser Renderingを比較しました。各プラットフォームには独自の長所と短所があります。
しかし、総合的に考えると、Puppeteerプロジェクトをオンラインにデプロイする予定であれば、Leapcellは優れた選択肢です。