Puppteerでキャプチャ画像を取得 part2
概要
エンジニアもどき2年目に入りました。色々あって以下を行うLambda関数を作成することになりました。
色々学びがあったので備忘録がわり兼アウトプットのために書くことにしました。
- 特定のページのキャプチャ取得
- 取得したキャプチャをS3に保存
- S3に保存したURLをDyanmoに記録
part2では2. 取得したキャプチャをS3に保存
の実装とデプロイまで行います。
part2での実装内容はこちら
前提
前回(part1)の続きです。part1に引き続き以下の準備は完了している前提です。
前回(part1)の実装内容はこちら
- nodejs
- ServerlessFramework
- yarn
- webpack
- iamのユーザ作成済み
実装作業
1. 準備
ローカルでの動作確認のためにローカルにS3のバケットを作成できるserverless-s3-local
を使用します。
# 追加
yarn add -D serverless-s3-local
続いてserveress.yml
にS3の設定を追加します。
service: puppeteer-capture
provider:
# ・・・ 省略 ・・・
# テーブル名やバケット名など環境変数
environment:
# ・・・ 省略 ・・・
# 追加1 : バケット名
CAPTURE_BUCKET: ${self:provider.environment.PREFIX}-capture-bucket
iamRoleStatements:
# 追加2 : S3の設定
- Effect: Allow
Action:
- 's3:PutObject'
- 's3:PutObjectAcl'
Resource: 'arn:aws:s3:::${self:provider.environment.S3_BUCKET}*'
# 追加3 : ローカルでの動作用設定
custom:
defaultStage: dev
s3:
port: 8081
directory: .s3
cors: false
# 追加3 : プラグイン
plugins:
- serverless-webpack
- serverless-s3-local
# ・・・ 省略 ・・・
# 追加4 : リソースの設定
resources:
Resources:
CaptureBucket:
Type: AWS::S3::Bucket
Properties:
BucketName: ${self:provider.environment.CAPTURE_BUCKET}
ローカルで起動できるか確認します。
sls s3 start -c ./serverless.yml
また、AWSのリソース(S3やDynamoDB)を操作する必要があるので、aws-sdk
を使用します。
# 追加
yarn add -D aws-sdk
Lambdaの実行環境には AWS SDK for JavaScriptが含まれているためdevDependenciesにのみ追加しています。
webpack.config.js
の外部依存にaws-sdk
を追加して準備は完了です。
// ・・・ 省略 ・・・
target: 'node',
// 追加
externals: ['chrome-aws-lambda', 'aws-sdk'],
// ・・・ 省略 ・・・
};
2. 実装
前回は取得したキャプチャ画像をローカルに書き出して保存していましたが、Lambdaは実行後、使用されたすべてのリソース(が破棄されてしまうので、S3に保存するように修正します。
// ・・・ 省略 ・・・
// 追加1 : S3のインポート
import { config, S3 } from 'aws-sdk';
// 追加2 : S3の設定とオプション(LOCALで実行した際の設定)
config.update({ region: process.env.AWS_REGION });
const s3Options = process.env.LOCAL
? {
s3ForcePathStyle: true,
accessKeyId: 'S3RVER',
secretAccessKey: 'S3RVER',
endpoint: new AWS.Endpoint('http://localhost:8081'),
}
: {};
// 追加3 : s3のクライアント/バケット名/アップロード関数
const s3 = new S3(options);
const bucket = process.env.CAPTURE_BUCKET;
const putObject = ({ key, body, contentType, acl }) => {
const params = {
Bucket: bucket,
Key: key,
Body: body,
ContentType: contentType,
ACL: acl,
};
console.log(params);
return s3.putObject(params).promise();
};
const getCapture = async (url) => {
// ・・・ 省略 ・・・
};
export const captureFunction = async event => {
// ・・・ 省略 ・・・
// 修正 : ファイルに書き出しからS3へアップロードするように変更
// Before : ファイル書き出し
// writeFileSync('/tmp/hoge.jpg', jpgBuf);
// After : S3へアップロード
try {
await putObject({
key: 'hoge.txt',
body: jpgBuf,
contentType: 'image/jpeg',
acl: 'public-read',
});
} catch (error) {
console.log(error);
return { statusCode: 500, body: error.message };
}
return { statusCode: 200, body: 'キャプチャの取得に成功しました。'};
};
注意する点はacl
、つまりアクセスコントロールリストにpublic-read
の設定を忘れるとS3にアップロードはできるもののAccess Deniedとなりリソースにアクセスができなくなってしまいます。
3. 動作の確認
まずはローカル環境での動作の確認です。
LOCAL=true sls invoke local --function captureFunction -c ./serverless.yml
LOCAL=true sls invoke local --function captureFunction --data '{"url":"https://qiita.com/"}' -c ./serverless.yml
実行して 200でレスポンスが帰ってくること、ローカルのバケットにキャプチャ画像が保存されていることを確認します。
バケットに保存されているhode.jpg._S3rver_object
をhoge.jpg
にリネームして開くと確認することができます。
4. デプロイと動作確認
デプロイします。
serverless deploy
実行し200でレスポンスが返ってくることを確認します。
また、AWSのコンソールからS3にアクセスしてバケットの中を確認します。
sls invoke --function captureFunction -c ./serverless.yml
sls invoke --function captureFunction --data '{"url":"https://qiita.com/"}' -c ./serverless.yml
以上でpart2の作業は完了です。
次はS3に保存した画像のURLをDynamoDBに書き出す処理までの実装を行います。
おわりに
- ACLのところで結構引っかかった(Bucketに保存できるもののアクセスできない)
- ローカルでのS3の使い方、ServerlessFrameworkでS3のバケットの作成など色々勉強になった
- 今回は日本語のページのキャプチャは必要なかったので対応していませんが、Lambdaのインスタンスに日本語フォントが含まれておらず、日本語を含むページのキャプチャした際に文字化けが発生します。(フォントを用意して設定する必要がある)
参考
Author And Source
この問題について(Puppteerでキャプチャ画像を取得 part2), 我々は、より多くの情報をここで見つけました https://qiita.com/yimi_getu/items/8418893e1e9d6ed9cea3著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .