serverless-chromeを使った記事は割とあるが、chromeのバージョンやらpythonのバージョンやらをいい感じにできない。
ecrを使うとlambdaにデプロイできるサイズ上限が一気にあがるので、普通に自前でchromeビルドして全部dockerimageに突っ込んじゃえばよくね?というもの。
ローカルでdockerを使います。
python3.9のlambdaで動かします。
ファイル
.
├── test.py
└── Dockerfile
コード
この例ではchrome103とlambda(python3.9)
Dockerfile
# chromeのセットアップ用
FROM public.ecr.aws/lambda/python:3.9 as build
RUN yum install -y unzip && \
curl -Lo "/tmp/chromedriver.zip" "https://chromedriver.storage.googleapis.com/103.0.5060.53/chromedriver_linux64.zip" && \
curl -Lo "/tmp/chrome-linux.zip" "https://www.googleapis.com/download/storage/v1/b/chromium-browser-snapshots/o/Linux_x64%2F1002910%2Fchrome-linux.zip?alt=media" && \
unzip /tmp/chromedriver.zip -d /opt/ && \
unzip /tmp/chrome-linux.zip -d /opt/
# 完成物
FROM public.ecr.aws/lambda/python:3.9
RUN yum install atk cups-libs gtk3 libXcomposite alsa-lib \
libXcursor libXdamage libXext libXi libXrandr libXScrnSaver \
libXtst pango at-spi2-atk libXt xorg-x11-server-Xvfb \
xorg-x11-xauth dbus-glib dbus-glib-devel -y
RUN pip install selenium
COPY --from=build /opt/chrome-linux /opt/chrome
COPY --from=build /opt/chromedriver /opt/
COPY test.py /var/task
CMD [ "test.handler" ]
test.py
import json
from selenium import webdriver
def handler(event, context):
options = webdriver.ChromeOptions()
options.binary_location = '/opt/chrome/chrome'
options.add_argument('--headless')
options.add_argument('--no-sandbox')
options.add_argument("--disable-gpu")
options.add_argument("--single-process")
options.add_argument("--disable-dev-shm-usage")
options.add_argument("--disable-dev-tools")
driver = webdriver.Chrome(options=options, executable_path="/opt/chromedriver")
driver.get("https://example.com")
print(driver.title)
return {
'statusCode': 200,
'body': json.dumps("done.")
}
print削除したりreturnを適当に変えたりしてください。
オプションとかはseleniumのドキュメント等で別途自分が必要そうなものを調べてみてください。
ビルド
% docker build -t {イメージ名} .
m1macの場合
% docker build --platform linux/amd64 -t {イメージ名} .
ecrにプッシュ
get-login-password のコマンドはマネジメントコンソールでecrのリポジトリを作成したあと見れます。
% aws ecr get-login-password --region {リージョン} --profile {使うプロファイル} | docker login --username AWS --password-stdin {awsアカウントid}.dkr.ecr.{リージョン}.amazonaws.com
% docker tag {イメージ名}:{タグ} {awsアカウントid}.dkr.ecr.{リージョン}.amazonaws.com/{イメージ名}:{タグ}
% docker push {awsアカウントid}.dkr.ecr.{リージョン}.amazonaws.com/{イメージ名}:{タグ}
lambda
マネジメントコンソールからecrにあげたイメージをもとにしたlambdaを適当にポチポチ作る。
補足
seleniumで色々やろうとすると重いからhtmlの解析自体はbeautifulsoupとかのパーサー使った方がパフォーマンスが云々、みたいなのもあるっぽいのでそこは必要に応じて。
参考