AWS LambdaでPlaywrightを使う(Python 3.10 + playwright1.50.0)

スクレイピングにseleniumを使用していましたが、playwrightがかなり直感的で使いやすかったことから活用を始めました。また、実行環境をlambdaにすることで他のアプリケーションから利用しやすくすることもできるため、その方法をまとめておきます。

# 開発環境
Windows10 Home 22H2
Python 3.10.4
~~playwright 1.42.0~~
playwright 1.50.0

# 1.playwrightを利用した機能を実装する
ローカルで普通に実装します。ブラウザオブジェクトを作る際には次のオプションを指定しておきます。今回は図書館のHPにアクセスして貸出状況を取得するスクレイパーを実装しています。

```python
    browser = playwright.chromium.launch(
        args=[
            "--disable-gpu",
            "--single-process",
        ],
    )

```

# 2.lambdaから利用するファイル構成にする
今回はappというフォルダの配下にまとめました。
app.py ... lambdaで呼び出されるlambda_handler()を含むモジュール
library_reader.py ... スクレイパー本体のモジュール
model.py ... データモデル定義用のモジュール


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89639/32749a74-9698-4da8-93ed-fd0eacf6f947.png)

app.pyの構成はこのようになります。lamnda_handler()の中でスクレイパーの処理を呼び出して、結果をresponseに渡すイメージです。いわゆる普通のlambda関数です。
```python
(略)

def lambda_handler(event, context):
    # lambda関数で行う適当な処理を定義

    (いろいろと略)

    # lambda関数からの戻り値を定義
    return {
        "statusCode": 200,
        "body": response,
    }
```

# 3.Dockerの準備
playwrightはchromeやedgeなどのブラウザエンジンを独自にインストールするので、lambda環境ですんなり動くようにコンテナ化しておきます。lambdaはコンテナをベースにした関数を駆動することもできます。

## Dockerfileの作成
Dockerfile自体はこのように作成しました

```dockerfile
# コンテナ内でlambda関数を配置するディレクトリ名を定義
ARG FUNCTION_DIR="/function"

# msが公開しているplaywright1.50.0用のイメージを使用する
FROM mcr.microsoft.com/playwright/python:v1.50.0-noble as build-image

# 依存ライブラリをインストールする
RUN apt-get update
RUN apt-get install -y g++
RUN apt-get install -y make
RUN apt-get install -y cmake
RUN apt-get install -y unzip
RUN apt-get install -y libcurl4-openssl-dev

# おまじない1
ARG FUNCTION_DIR

# lambda関数を配置するディレクトリを作成する
RUN mkdir -p ${FUNCTION_DIR}

# lambda関数のコード一式をコピーする
COPY app/* ${FUNCTION_DIR}

# runtime interface clientというライブラリをインストールする
RUN python -m pip install --upgrade pip
RUN python -m pip install --target ${FUNCTION_DIR} playwright awslambdaric

# その他のランタイムをインスト＾るする（お好みで）
RUN python -m pip install --target ${FUNCTION_DIR} boto3 pandas

# マルチステージビルドのおまじない
FROM mcr.microsoft.com/playwright/python:v1.50.0-noble

# おまじない2
ARG FUNCTION_DIR

# 作業ディレクトリを移動
WORKDIR ${FUNCTION_DIR}

# おまじない3
COPY --from=build-image ${FUNCTION_DIR} ${FUNCTION_DIR}

# 実行された時に発行するコマンドを指定する
ENTRYPOINT [ "/usr/bin/python", "-m", "awslambdaric" ]
CMD [ "app.lambda_handler" ]
```

これでローカル側の準備ができたので、次はAmazon ECRの準備をします。

## AmazonECRにリポジトリを作成
Amazon ECRにリポジトリを作成します。名前は```lamda-playwright```としておきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89639/b4c4ccb9-9dbb-4960-92c9-a77bfa1d1207.png)

## コンテナイメージのbuildとpush
リポジトリが作成されたら```プッシュコマンドの表示```から

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89639/f5065e21-94c3-5452-8711-2bc633de70a5.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89639/adf98328-28d5-b930-13dd-27ea2cb92983.png)

一番上にあるこのようなコマンドを打って、リポジトリに認証を通しておきます。伏字部分はAWSアカウントIDです。環境はwindowsですがlinux用のコマンドを打っても特に問題ありませんでした。

```
aws ecr get-login-password --region ap-northeast-1 | docker login --username AWS --password-stdin [YOUR_AWS_ACCOUNT_ID].dkr.ecr.ap-northeast-1.amazonaws.com
```

このようになれば成功。
```
Login Succeeded
```

次に、Dockerfileが置いてあるフォルダでコンテナイメージをビルドします。

```
docker build -t lambda-playwright .
```

続けてタグを設定します。
```
docker tag lambda-playwright:latest [YOUR_AWS_ACCOUNT_ID].dkr.ecr.ap-northeast-1.amazonaws.com/lambda-playwright:latest
```

最後にリポジトリにpushします。
```
docker push [YOUR_AWS_ACCOUNT_ID].dkr.ecr.ap-northeast-1.amazonaws.com/lambda-playwright:latest
```

push完了。ネットワークが遅いと数分かかります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89639/2e08d493-e140-9f22-90dd-cadc4ec560a8.png)


# 4.Lambda関数を作成
コンソールのLambda関数作成画面で```コンテナイメージ```を選択し、関数名をつけて、コンテナイメージURIを指定します。イメージを参照ボタンから選択するだけで良いです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89639/751f520f-2684-00ba-0a14-fac0ebfaecea.png)

作成したlambda関数はコードがコンテナ内にあるのでこのように表示されます。実行については通常のlambdaと同様にできます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89639/67d85278-1919-fdc7-e4de-b04ef3bf7840.png)

テスト実行し、正しく動作することを確認します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89639/4c5c54aa-0327-380c-112f-d5a84a25bddd.png)

# 参考にした情報
[How to run Playwright with Python in AWS Lambda](https://www.cloudtechsimplified.com/playwright-aws-lambda-python/)