LoginSignup
6

More than 3 years have passed since last update.

posted at

AWS LambdaでNokogiriを動かす

近々、AWS Lambdaを使って簡易的なクローラを作る予定があったので
Lambda上でNokogiriが使えるか 検証しました。

開発環境

ローカルの開発環境はMac、クローラはRubyで実装します。

ポイント

クローリングに必要となるGemである「Nokogiri」はネイティブライブラリを含むGemであるため、
Mac上でビルドしてAWSへデプロイすると「cannot load such file -- nokogiri」が発生します。

これを回避するため、AWS SAMを用いて雛形作成した上で、
sam build --use-container」を実行しAmazonLinux2のDockerコンテナ上でビルドを行いました。

AWS SAM CLIでHello World

AWS SAM CLIを使ってRubyのLambdaハンドラの雛形を作成します。
アプリの名前が実際に作ろうとしているクローラの名前になっていますので、適宜置き換えてください。

$ sam init --runtime ruby2.5 --name sample_app
$ cd sample_app
$ sam build
$ sam local invoke HelloWorldFunction --event event.json

参考: https://aws.amazon.com/jp/about-aws/whats-new/2018/04/aws-sam-cli-releases-new-init-command/

Nokogiriのインストール

今回はLambda上でスクレイピングツールであるNokogiriを動かす必要があります。
このGemはネイティブライブラリが含まれるため、ローカル環境(今回はMac)でインストールするとLambda上でエラーとなります。

が、AWS SAM CLIは以下コマンドでネイティブライブラリも含めて良い感じにビルドしてくれるコマンドを提供してくれています。便利ですね。

hello_world/Gemfile
source "https://rubygems.org"

gem "httparty"
gem "nokogiri" # 追記
gem "robotex"  # 追記

追記先はルートのGemfileではありませんので注意してください。
cannot load such file -- nokogiri が起こる原因となります。

Nokogiriを使うLambdaハンドラを実装

動作確認のためLambdaハンドラの処理も修正します。

hello_world/app.rb
require "bundler/setup"
Bundler.require

URL='https://www.google.com/'

def lambda_handler(event:, context:)
  charset = nil

  robotex = Robotex.new
  robotex.allowed?(URL)
  robotex.delay!(URL)

  html = open(URL) do |f|
    charset = f.charset
    f.read
  end

  doc = Nokogiri::HTML.parse(html, nil, charset)

  {
    statusCode: 200,
    body: {
      page_title: doc.title,
    }.to_json
  }
end

ローカルの開発環境で動作確認

ビルドして実行してみましょう。
GoogleのTOPページのタイトルが取得できました。

$ sam build --use-container
$ sam local invoke HelloWorldFunction --event event_file.json 
{"statusCode":200,"body":"{\"page_title\":\"Google\"}"}

デプロイ

AWS SAM CLIを使ってデプロイします。

$ sam package --output-template-file output.yaml --s3-bucket sample_app
$ sam deploy --template-file output.yaml --stack-name sample_app --capabilities CAPABILITY_NAMED_IAM

ただし、 sam package--template-file オプションを指定すると、vendor配下がアップロードされない問題が発生しました。 --template-file は設定しないようにしましょう。

AWSコンソールにログインして、Lambdaを実行すると無事成功しました。

Lambda_Management_Console.png

参考

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
What you can do with signing up
6