はじめに
この記事は、mohikanz Advent Calendar 2019の11日目の記事です。
去年は、マイコンネタでした。
今年は、AWSで日頃便利に使わせてもらっている技術ネタについて書きます。
あるプロジェクトで、Webサイトを定期的にキャプチャして、S3に保存しておきたいなぁと言う事があり、それならばサーバレスで挑戦してみようと言うことになり、それをやってみたときの記事になります。
Lambdaは便利ですよね。何よりお安いですし。
必要な知識
- Python
- AWS Lambda
- Selenium
事前準備
headless chromeを使いますので、いくつか事前準備が必要です。
Lambda Layers
Lambdaのファイルサイズ上限に引っかかるので、Lambda Layersにheadless chromeを用意します。
GitHubに置いておきましたので、ご自由にお使いください。
Lambda Layersは、マネジメントコンソールからアップロードが出来ます。
日本語フォント
IPAexフォントがあると文字化けしませんので、あらかじめダウンロードしておいてください。
./fonts
ディレクトリに保存しておきます。
Lambda Layersに含めると50MBを超えてしまうので、Lambdaの方に追加します。
- 2書体パック(IPAex明朝(Ver.002.01)、IPAexゴシック(Ver.002.01))
Lambdaの作成
Serverless Frameworkを使って構築します。
$ sls create --template aws-python3 --path headless-chrome
service: headless-chrome
provider:
name: aws
runtime: python3.6
memorySize: 1600
timeout: 120
stage: ${opt:stage, 'dev'}
region: ap-northeast-1
# 権限設定
iamRoleStatements:
- Effect: "Allow"
Action:
- "s3:GetObject"
- "s3:PutObject"
Resource: "arn:aws:s3:::headless-chrome-${self:provider.stage}/*"
functions:
chrome:
handler: chrome.lambda_handler
description: Headless Chrome
environment:
TZ: Asia/Tokyo
STAGE: ${self:provider.stage}
S3BUCKET: headless-chrome-${self:provider.stage}
package:
# フォントを追加する
include:
- '.fonts/**'
layers:
- arn:aws:lambda:ap-northeast-1:xxxxxxxxxxxx:layer:headless_chrome_python360:1
Lambdaのソースコード
from selenium import webdriver
import boto3
import json
import os
import time
os.environ['HOME'] = '/var/task'
def lambda_handler(event, context):
options = webdriver.ChromeOptions()
options.add_argument("--headless")
options.add_argument("--disable-gpu")
# options.add_argument("--window-size=3408x2156")
options.add_argument("--window-size=1704x1078")
options.add_argument("--disable-application-cache")
options.add_argument("--disable-infobars")
options.add_argument("--no-sandbox")
options.add_argument("--hide-scrollbars")
options.add_argument("--enable-logging")
options.add_argument("--log-level=0")
options.add_argument("--v=99")
options.add_argument("--single-process")
options.add_argument("--ignore-certificate-errors")
options.add_argument("--homedir=/tmp")
options.binary_location = "/opt/bin/headless-chromium"
bucket = os.environ.get("S3BUCKET", "")
s3 = boto3.client('s3')
driver = webdriver.Chrome(
"/opt/bin/chromedriver", chrome_options=options)
driver.get("https://www.google.co.jp")
time.sleep(5)
driver.save_screenshot("/tmp/shot.png")
driver.close()
s3.upload_file(Filename="/tmp/shot.png",
Bucket=bucket,
Key="hoge.png")
return "ok"
実行してみた
$ sls deploy -v
$ sls invoke -f chrome
こんな感じになりました。
さいごに
Seleniumを使いこなせる人は、CI/CDに組み込んだりしてみると、リリースの動作確認まで出来ちゃうので、夢が広がりますね。
chromeはfileプロトコルも使えるので、ローカルに置いたファイル(Lambdaが動いてる実行環境)を使うこともできます。