puppeteerをAWS Lambdaで利用する
AWS Lambda
は、いわゆるFaaS(Function as a Service)
の1つです。AWS Lambda
を使用することで、サーバーのプロビジョニングや管理をすることなく、コードを実行できます。
なんらかのイベントをトリガーとして、処理を行うためには適しているサービスです。
しかし、puppeteer
をAWS Lambda
上で何かの処理を自動化する場合、以下の制約がネックになります。
- デプロイパッケージサイズ
- 50 MB(zip圧縮済み、直接アップロード)
- 250 MB(解凍、レイヤーを含む)
- 3 MB(コンソールエディタ)
puppeteer
を普通に利用するとchronium
を同梱しているため、どうしても50MBの制限を超えてしまいます。この制限を回避するためには以下で公開いただいているような、軽量なChromium Binary
を利用する必要があります。
- alixaxel/chrome-aws-lambda: Chromium Binary for AWS Lambda and Google Cloud Functions
- adieuadieu/serverless-chrome: 🌐 Run headless Chrome/Chromium on AWS Lambda
今回は、chrome-aws-lambda
を利用する手順を紹介します。
1. AWS Lambda Layerに登録するZIPアーカイブ(chromium + puppeteer)を作成
AWS Lambda Layer
とは、ライブラリ、カスタムランタイム、またはその他の依存関係を含むZIPアーカイブです。
このAWS Lambda Layer
を利用してデプロイパッケージを小さくすることで、AWS Lambda
上でpuppeteer
を利用可能とします。
chrome-aws-lambda
を利用する場合は、以下のコマンドを実行してAWS Lambda Layer
に登録するZIPアーカイブを作成します。
git clone --depth=1 https://github.com/alixaxel/chrome-aws-lambda.git && \
cd chrome-aws-lambda && \
make chrome_aws_lambda.zip
2. AWS Lambda Layerに作成したZIPアーカイブを登録
AWS Console > AWS Lambdaから、レイヤーを作成します。

ここで、先ほど作成したchrome_aws_lambda.zip
を指定します。また、互換性のあるランタイムとしてNode.js 10.x
, Node.js 12.x
を指定して登録します。

3. AWS Lambda関数の作成とレイヤー追加
続いて、ぽちぽちと関数を作成していきます。


任意の名前で関数を作成した後、「レイヤーの追加」から先ほど登録したレイヤーを追加します。(ここでは一度登録し直したためバージョン2になっていますが、初期登録の場合はバージョン1になります)


続いて、実際のコードを登録します。ここでは下記のサンプルコードを利用します。

const chromium = require('chrome-aws-lambda');
exports.handler = async (event, context, callback) => {
let result = null;
let browser = null;
try {
browser = await chromium.puppeteer.launch({
args: chromium.args,
defaultViewport: chromium.defaultViewport,
executablePath: await chromium.executablePath,
headless: chromium.headless,
ignoreHTTPSErrors: true,
});
let page = await browser.newPage();
await page.goto(event.url || 'https://example.com');
result = await page.title();
} catch (error) {
return callback(error);
} finally {
if (browser !== null) {
await browser.close();
}
}
return callback(null, result);
};
4. 実行時の設定変更
chrome-aws-lambda
の要求するメモリは、最小512MB, 推奨1600MB以上とされています。
ここでは、最小512MBと、タイムアウトをデフォルトの3秒から1分に設定を変更しました。
(タイムアウトをデフォルトの3秒のままにしていたら、puppeteer
が起動するまでに3秒以上かかり、タイムアウトのエラーが発生しました)


5. テスト実行
以下の「テスト」をクリックして、新しいテストイベントの設定を行います。今回は、デフォルトのまま登録します。


関数コードの「Test」を実行すると、正しくレスポンスが返ってきました。Response: "Example Domain"

まとめ
上記の手順により、puppeteer
をAWS Lambda
で実行する方法を確立できました。
これにより、AWS Lambda
の柔軟な実行環境を手に入れました。
後はイベント駆動でスクレイピングや任意の処理を組み込むなど、できることは多そうです。
Related contents

TECH
2020.04.20

TECH
2020.01.30

TECH
2017.08.27

TECH
2017.08.22

TECH
2014.03.15

TECH
2014.02.11

TECH
2014.02.11