Edited at

AWS Lambda上のheadless chromeをPythonで動かす


はじめに


  • この記事では、AWS Lambda上でheadless chromeをPythonで動かす方法を紹介します。


  • AWS Lambdadockerを使うので、導入してあることを前提とします。

  • 今回書いたコードはhttps://github.com/nabehide/lambda_headless_chrome_pythonにあげました。

  • Lambdaにデプロイするファイルの作成はMac OS上で行いました。

  • 以下、適当なフォルダを作成して、その中で作業していきます。


$ mkdir lambda_headless_chrome_python
$ cd lambda_headless_chrome_python


  • もしくは、githubからサンプルコードをクローンしてきてください。

$ git clone https://github.com/nabehide/lambda_headless_chrome_python.git

$ cd lambda_headless_chrome_python


手順


lambda_function.py 作成


  • googleにアクセスして、ページのタイトルを取ってくるだけの操作をやってみます。


lambda_function.py


from selenium import webdriver

def lambda_handler(event, context):
options = webdriver.ChromeOptions()

# のちほどダウンロードするバイナリを指定
options.binary_location = "./bin/headless-chromium"

# headlessで動かすために必要なオプション
options.add_argument("--headless")
options.add_argument("--disable-gpu")
options.add_argument("--window-size=1280x1696")
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("--single-process")
options.add_argument("--ignore-certificate-errors")
options.add_argument("--homedir=/tmp")

driver = webdriver.Chrome(
"./bin/chromedriver",
chrome_options=options)
driver.get("https://www.google.co.jp")
title = driver.title
driver.close()
return title



serverless-chromiumのダウンロード



  • serverless-chrome というLambda上で動くheadless-chromiumを使わせていただきます。

  • 最新版はPythonで動かない(2018年4月27日現在 [参照])ため、v1.0.0-37を入れます。


$ mkdir -p bin/
$ curl -SL https://github.com/adieuadieu/serverless-chrome/releases/download/v1.0.0-37/stable-headless-chromium-amazonlinux-2017-03.zip > headless-chromium.zip
$ unzip headless-chromium.zip -d bin/
$ rm headless-chromium.zip


chromedriverのダウンロード


  • 上でダウンロードしたChromiumのバージョンに対応したchromedriverのバージョン(2.37)を選んでダウンロードします。

$ curl -SL https://chromedriver.storage.googleapis.com/2.37/chromedriver_linux64.zip > chromedriver.zip

$ unzip chromedriver.zip -d bin/
$ rm chromedriver.zip


seleniumのダウンロード


  • seleniumなど、pipでインストールするパッケージは、Lambdaにアップロードするファイルに含まれていないといけません。

  • しかし、例えばMacの環境でpipを使うと、Mac環境で実行可能なファイルがダウンロードされることになります。

  • そこで、Amazon Linux2で実行可能なものをダウンロードするために、dockerを使います。


  • lambda/lambci という、Lambdaの環境にPythonが入ったものを使わせていただきます。

  • 下記のDockerfileを作成します。


Dockerfile

FROM lambci/lambda:build-python3.6

ENV AWS_DEFAULT_REGION ap-northeast-1
ENV APP_DIR /var/task

ADD . .

CMD pip install -r requirements.txt -t $APP_DIR && \
zip -9 deploy_package.zip lambda_function.py && \
zip -r9 deploy_package.zip *



  • docker image を作成して、パッケージングします。

$ docker build -t lambda_headless_chrome .

$ docker run -v "${PWD}":/var/task lambda_headless_chrome


  • これでlambdaにアップロードするzipファイル deploy_package.zipができます。


Lambdaで実行する


  • AWSコマンドラインインターフェース(CLI)を導入していない場合は、下記コマンドで導入します。

$ pip install awscli


  • 下記コマンドでapiキーなども設定しておきます。

$ aws configure


  • AWSコンソールでS3のバケットとroleを作成します。roleのpolicyに AWSLambdaFullAccess をアタッチしておきます。

  • deploy_pakcage.zipをLambdaにアップロードして、関数を作成します。(リージョンやロール、バケットの名前などは適宜変えて実行します。)

$ aws s3 cp deploy_package.zip s3://YOUR_BUCKET_NAME

$ aws lambda create-function --region ap-northeast-1 --function-name lambda_headless_chrome_python --runtime python3.6 --role YOUR_ROLE_NAME --code S3Bucket=YOUR_BUCKET_NAME,S3Key=deploy_package.zip --handler lambda_function.lambda_handler --memory-size 512 --timeout 300


  • lambdaにアクセスすると、lambda_headless_chrome_python という関数ができているので、「テスト」ボタンで実行確認ができます。


さいごに

AWS Lambda上でheadless chromeをPythonで動かす方法を書きました。

あとはlambda_function.pyを好きなように書いて、requirements.txtに必要なパッケージを追加して、実行するだけです!