Python
AWS
pip
lambda

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

More than 1 year has 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

権限がないですと

スクリーンショット 2016-04-17 22.59.59.png

AWSLambdaFullAccessを追加してまた実行

エラー・・

ここでdots.女子部のもくもく会が終盤に差し迫りビールが支給されたのでふてくされて飲んでました。
ビール半分くらい開けて、いいかんじに酔ってきたのでやけくそで実行したら、、、

$ lambda-uploader
λ Building Package
λ Uploading Package
λ Fin

ポリシーのアタッチ反映に時間かかってたみたいでした。
余裕持って開発するのって重要ですね。

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