AWS LambdaでScrapyを動かす
pip install が必要なので、下記を使って動作確認とデプロイパッケージ作る方向で調査。
https://github.com/lambci/docker-lambda
この Docker イメージを使うと、AWS とほぼ同じような環境を Docker 上に再現して Lambda 関数を実行できる。また、レイヤー作成用に gcc などよく使うライブラリがインストールされた Docker イメージもセットで公開されており、EC2 上で開発する必要がなくなるので非常に便利!
まずはコンテナ内からボリューム割当したローカルディレクトリに pip install する。Python のバージョンは現在使っている 2.7 で。
docker run --rm -v "$PWD":/var/task lambci/lambda:build-python2.7 pip install -r requirements.txt -t python
とりあえず scrapy コマンドを呼ぶだけの lambda_function.py を作る。
import subprocess
def lambda_handler(event, context):
subprocess.call(["scrapy", "crawl", "spider_name"])
その後、ライブラリをレイヤーとして使って実行。
docker run --rm -v "$PWD":/var/task:ro,delegated -v "$PWD"/python:/opt:ro,delegated lambci/lambda:python2.7 lambda_function.lambda_handler
するとコマンドが見つからないとのエラー。
[Errno 2] No such file or directory: OSError Traceback (most recent call last): File "/var/task/lambda_function.py", line 13, in lambda_handler subprocess.call(["scrapy", "crawl", "spider_name"])
PATH に追加して呼び出せるようにした。
import subprocess
def lambda_handler(event, context):
os.environ['PATH'] = os.environ['PATH'] + ":/opt/python/bin"
subprocess.call(["scrapy", "crawl", "spider_name"])
今度はこのエラー。
Traceback (most recent call last): File "/opt/python/bin/scrapy", line 5, in from scrapy.cmdline import execute ImportError: No module named scrapy.cmdline
コマンド実行ではなく CrawlerProcess を使えば OK。
from scrapy.crawler import CrawlerProcess
from scrapy.utils.project import get_project_settings
def lambda_handler(event, context):
process = CrawlerProcess(get_project_settings())
process.crawl('spider_name')
process.start()
https://scrapy-ja.readthedocs.io/ja/latest/topics/practices.html#scrapy
デプロイパッケージ作成
レイヤー
zip -r scrapy.zip python
Lambda 関数
zip -r deploy.zip spider_name lambda_function.py scrapy.cfg
2022.11.14追記
いつの間にか Lambda がコンテナをサポートしていたらしく、lambci/docker-lambda は更新をやめた様子。Python 3.8 で止まっている。Lambda もだんだん Python のバージョンが上がって足切りされていくので、公式のコンテナ手順に移行した。
コメントを残す