2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

lambda rubyでクロールしてs3にhtmlを出力するをAWS SAMで

Last updated at Posted at 2019-04-08

概要

  • ulrをクロールしたhtmlをS3に保存するlambda functionをSAMでdeployした
  • ふつーにクロールすると1 url辺り5秒かかるとして1000url 5000秒。lambdaを使うと並列しょりできるので、所要時間はinvokeの時間+5秒なのでだいたい60秒ぐらいで終わる
  • lambdaはruby

手順

AWS SAM インストール

https://docs.aws.amazon.com/ja_jp/serverless-application-model/latest/developerguide/serverless-sam-cli-install-mac.html
https://aws.amazon.com/jp/blogs/developer/announcing-ruby-build-support-for-aws-sam-cli/

brew tap aws/tap

brew install aws-sam-cli

ひな形作成

sam init --runtime ruby2.5 --name hello-ruby-sam
cd hello-ruby-sam

バケット作る

  • SAM保存する & クロールしたhtmlを保存するバケットを作ります。(別々がいいですが、今回は手間を省略)
aws s3 mb s3://YOUR_NEW_BUCKET_NAME --region ap-northeast-1

コード書く

  • urlのhtmlを取得してs3に保存するメソッドです。これがlambdaで実行されます。
  • urlをハッシュにしてフォルダ名にして、その中にクロール日付(yyyymmdd.html)がついたファイルが作成されます。
    • なのでページを取得するときはハッシュをキー Digest::SHA256.hexdigest(url) にして取得して下さい(urlをフォルダ名にしたいけどそれだとうまくいかないので)
    • そこら辺は説明省略
  • awsのキーとかはご自分のキーなどに適宜書き換えて下さい。
hello-ruby-sam/crawl_url/app.rb
require 'json'
require 'open-uri'
require 'aws-sdk-s3'

BUCKET_NAME = 'bucket-name'
BUCKET_REGION = 'bucket_region'
AWS_ACCESS_KEY = 'aws_access_key'
AWS_SECRET_KEY = 'aws_secret_key'

def lambda_handler(event:, context:)
  url = event['url']
  html = open(url) do |f|
    f.read
  end

  s3 = Aws::S3::Resource.new(
      region: BUCKET_REGION,
      credentials: Aws::Credentials.new(AWS_ACCESS_KEY, AWS_SECRET_KEY)
  )
  obj = s3.bucket(BUCKET_NAME).object("#{Digest::SHA256.hexdigest(url)}/#{Time.now.strftime('%Y%m%d')}.html")

  obj.put(body: html)
end

テンプレート

最後にテンプレートを編集。いらないところをバッサリと削ります。

hello-ruby-sam/template.yaml
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
  CrawlUrl

# More info about Globals: https://github.com/awslabs/serverless-application-model/blob/master/docs/globals.rst
Globals:
  Function:
    Timeout: 30

Resources:
  CrawlUrlFunction:
    Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
    Properties:
      FunctionName: CrawlUrl
      CodeUri: crawl_url/
      Handler: app.lambda_handler
      Runtime: ruby2.5

Outputs:
  CrawlUrlFunction:
    Description: "CrawlUrl Lambda Function ARN"
    Value: !GetAtt CrawlUrlFunction.Arn
  CrawlUrlFunctionIamRole:
    Description: "Implicit IAM Role created for CrawlUrl function"
    Value: !GetAtt CrawlUrlFunctionRole.Arn

デプロイ

デプロイします。
ついでにAWSのcloudformationを開いて見ているとごりごり動くのがわかるので楽しいです。

sam build
sam package \
    --template-file template.yaml \
    --output-template-file packaged.yaml \
    --s3-bucket バケット名

sam deploy \
    --template-file packaged.yaml \
    --stack-name sam-app \
    --capabilities CAPABILITY_IAM
  • lambadaのファンクションが作られていれば成功です。

使う

  • irbで試します。
  • aws-sdk のgemが入った状態、 invoke(url) のurlの箇所に任意のurlを入れるて、S3にurlのhtmlが保存されます。
require 'aws-sdk'

BUCKET_NAME = 'bucket-name'
BUCKET_REGION = 'bucket_region'
AWS_ACCESS_KEY = 'aws_access_key'
AWS_SECRET_KEY = 'aws_secret_key'


def invoke(url)
  client = Aws::Lambda::Client.new(region: 'ap-northeast-1', credentials: Aws::Credentials.new(AWS_ACCESS_KEY, AWS_SECRET_KEY))

  req_payload = { url: url }
  payload = JSON.generate(req_payload)
  client.invoke({
                          function_name: 'CrawlUrl',
                          invocation_type: 'Event',
                          log_type: 'None',
                          payload: payload
                      })
end

invoke('https://ほしいurl')

以上

わからなかったこと

deploy時awsのキーを環境変数などで渡す方法がわからない。

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?