Headless-Chrome on AWS Lambda
以下の記事を参考にAWS Lambda上でHeadless-Chromeを動かしてみました。
注) Serverlessは事前にインストールしておく必要があります。
AWS Lambda上でのWebクローリング実行に少し近づいてきました。
- Serverlessを使って簡単にAWS Lambda Layers上でHeadless Chromeを動かす - フリーランチ食べたい
- yai333/Selenium-UI-testing-with-AWS-Lambda-Layers: Selenium UI testing with AWS Lambda Layers
ファイル構成
適当なディレクトリ以下に二つのディレクトリ(lambda、selenium-layer)を作成していきます。
mkdir crowler(任意) cd crowler $ tree -L 2 . ├── lambda │ ├── handler.py │ └── serverless.yml ├── selenium-layer │ ├── chromedriver │ ├── selenium │ └── serverless.yml
selenium-layer
selenim(pythonモジュール)とchromedriver(chromedriver, headless-chrome)をLayerとして登録します。
参照した記事は、chromedriverディレクトリ以下の構成が少しわかりにくかったです。
chromedriver
$ cd selenium-layer $ mkdir chromedriver $ cd chromedriver # headless-chromiumダウンロード $ curl -SL https://github.com/adieuadieu/serverless-chrome/releases/download/v1.0.0-41/stable-headless-chromium-amazonlinux-2017-03.zip > headless-chromium.zip $ unzip headless-chromium.zip $ rm headless-chromium.zip # chromedriverダウンロード $ curl -SL https://chromedriver.storage.googleapis.com/2.37/chromedriver_linux64.zip > chromedriver.zip $ unzip chromedriver.zip $ rm chromedriver.zip $ tree . ├── chromedriver(実行モジュール) └── headless-chromium(実行モジュール)
selemium
pythonモジュールを追加します。
$ cd selenium-layer $ mkdir selenium $ cd selenium $ pip install -t selenium/python/lib/python3.6/site-packages selenium $ tree -L 3 . └── python └── lib └── python3.6
serverless.yml
chromedriverとseleniumをLayer定義します。
$ cat serverless.yml service: selenium-layer provider: name: aws runtime: python3.6 stage: dev region: ap-northeast-1 layers: selenium: path: selenium description: selenium layer CompatibleRuntimes: - python3.6 chromedriver: path: chromedriver description: chrome driver layer CompatibleRuntimes: - python3.6 resources: Outputs: SeleniumLayerExport: Value: Ref: SeleniumLambdaLayer Export: Name: SeleniumLambdaLayer ChromedriverLayerExport: Value: Ref: ChromedriverLambdaLayer Export: Name: ChromedriverLambdaLayer
deploy
deployします。awscliのインストールおよび設定は事前に済ませておく必要があります。
$ serverless deploy
AWSコンソールで登録内容を確認することができます。
lambda
登録したselenium-layerを使う関数をLambdaに登録します。
handler.py
Lambda登録したモジュールは/opt以下に配置されます。
$ cat handler.py from selenium import webdriver from selenium.webdriver.chrome.options import Options def hello(event, context): options = Options() options.binary_location = '/opt/headless-chromium' options.add_argument('--headless') options.add_argument('--no-sandbox') options.add_argument('--single-process') options.add_argument('--disable-dev-shm-usage') driver = webdriver.Chrome('/opt/chromedriver', chrome_options=options) driver.get('https://qiita.com/') body = f"Blog title is: {driver.title}" driver.close(); driver.quit(); response = { "statusCode": 200, "body": body } return response
serverless.yml
service: crawler-with-selenium provider: name: aws runtime: python3.6 stage: dev region: ap-northeast-1 timeout: 900 environment: SELENIUM_LAYER_SERVICE: selenium-layer functions: hello: handler: handler.hello layers: - ${cf:${self:provider.environment.SELENIUM_LAYER_SERVICE}-${opt:stage, self:provider.stage}.SeleniumLayerExport} - ${cf:${self:provider.environment.SELENIUM_LAYER_SERVICE}-${opt:stage, self:provider.stage}.ChromedriverLayerExport}
deploy
$ serverless deploy
実行
$ seleverless invoke -f hello { "statusCode": 200, "body": "Blog title is: Qiita" }
実行した時に以下のエラーが発生しましたが、しばらく時間をおいたら正常に動作しました。deployには少し時間がかかるのかも。
Serverless Error --------------------------------------- The role defined for the function cannot be assumed by Lambda.