Edited at

AWS Lambda PythonでS3にrequestで取得したものをアップロードする

More than 3 years have passed since last update.

dots.女子部のもくもく会で、AWS Lambdaを使ってクローラーを作ろうと思い、重い腰を上げました。

腰、本当に重いんですよ。

Lambdaといえば月100万回無料なので、1分間に23回も実行できるんだと思います。

Lambdaで作るクローラー/スクレイピングが参考になりそうなので、最初はこれを見ながらS3にrequestで取得したものをとりあえずアップロードしようと思いました。

言語はもちろんPythonで!

import boto3

import requests

BUCKET = 'test_requests'
s3 = boto3.client('s3')

def lambda_handler(event, context):
key = 'corp.camon.tokyo'
target_url = 'http://corp.camon.tokyo'
target_html = requests.get(target_url).text
s3.put_object(Bucket=BUCKET, Key=key, Body=target_html)

さすがAWS Lambda楽勝だぜ!って思いながらTestボタンを押すと・・

"errorMessage": "Unable to import module 'lambda_function'"

requestsが読み込めなくてエラー\(^o^)/

AWS Lambdaでpip installするにはどうすればいいかとぐぐったらこんな記事に出会いました。

AWS Lambda Pythonをlambda-uploaderでデプロイ

※要AWS CLI

pip install lambda-uploader

ディレクトリを作って、さっき書いたソースコピーして、lambda.jsonとrequirements.txtを用意しました。


test_requests.py

import boto3

import requests

BUCKET = 'test_requests'
s3 = boto3.client('s3')

def lambda_handler(event, context):
key = 'corp.camon.tokyo'
target_url = 'http://corp.camon.tokyo'
target_html = requests.get(target_url).text
s3.put_object(Bucket=BUCKET, Key=key, Body=target_html)



lambda.json

  {

"name": "test_requests",
"description": "test requests",
"region": "ap-northeast-1",
"handler": "test_requests.lambda_handler",
"role": "arn:aws:iam::????????????:role/lambda_s3_exec_role",
"timeout": 300,
"memory": 128
}


requirements.txt

requests


構成はこんなかんじです。

$ tree

.
├── lambda.json
├── requirements.txt
└── test_requests.py

0 directories, 3 files

用意できたのでコマンド実行。

lambda-uploader

λ Building Package

λ Uploading Package
⁉️ Unexpected error. Please report this traceback.
Traceback (most recent call last):
File "/usr/local/lib/python2.7/site-packages/lambda_uploader/shell.py", line 151, in main
_execute(args)
File "/usr/local/lib/python2.7/site-packages/lambda_uploader/shell.py", line 82, in _execute
upldr.upload(pkg)
File "/usr/local/lib/python2.7/site-packages/lambda_uploader/uploader.py", line 112, in upload
self.version = self.upload_new(pkg)
File "/usr/local/lib/python2.7/site-packages/lambda_uploader/uploader.py", line 89, in upload_new
Publish=self._config.publish,
File "/usr/local/lib/python2.7/site-packages/botocore/client.py", line 301, in _api_call
return self._make_api_call(operation_name, kwargs)
File "/usr/local/lib/python2.7/site-packages/botocore/client.py", line 398, in _make_api_call
raise ClientError(parsed_response, operation_name)
ClientError: An error occurred (AccessDeniedException) when calling the CreateFunction operation: User: arn:aws:iam::????????????:user/WakanaYoshizawa is not authorized to perform: lambda:CreateFunction

権限がないですと

AWSLambdaFullAccessを追加してまた実行

エラー・・

ここでdots.女子部のもくもく会が終盤に差し迫りビールが支給されたのでふてくされて飲んでました。

ビール半分くらい開けて、いいかんじに酔ってきたのでやけくそで実行したら、、、

$ lambda-uploader

λ Building Package
λ Uploading Package
λ Fin

ポリシーのアタッチ反映に時間かかってたみたいでした。

余裕持って開発するのって重要ですね。

Lambdaでいろいろ出来そうなのでもっといろいろいじってみます\(^o^)/