Quantcast
Channel: Node.jsタグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 9086

Puppeteer on Lambda (Node.js 12.x) で日本語ページのキャプチャを取る方法 簡単

$
0
0

やりたいこと

Lambda上でPuppeteerを動かしてキャプチャを取るとき、日本語フォントを正しく表示させる。
(デフォルトではLambdaに日本語フォントが入っていないため、何もしないと日本語がすべて豆腐になってしまうのだ。)

環境

  • AWS Lambda
    • Node.js 12.x
  • ローカル
    • Windows10
    • Node.js v12.16.2
    • npm 6.14.4

やり方(ざっくり)

  • Lambda Layerに日本語フォントをzip化してアップロードする。
  • Lambda関数にそのLayerを追加する。
  • Lambda関数内でLayerのフォントファイルを参照できるようにindex.jsでprocess.env['HOME'] = "/opt";を定義する。

やり方(詳細)

ローカルのディレクトリ構成
puppeteer_sample
├─ modules # Layerに登録するnpmモジュール群│   ├─ node_modules
│   └─ package-lock.json
├─ .fonts  # Layerに登録する日本語フォント置き場│   ├─ ipag.ttf
│   ├─ ipagp.ttf
│   ├─ NotoSansCJKjp-Bold.otf
│   └─ NotoSansCJKjp-Regular.otf
└─ lambda  # Lambda本体のコード群└─ index.js

Lambda上でpuppeteerを動作させる

こちらの記事が非常に分かりやすく、参考になりました。
参考記事は、LambdaのランタイムにNode.js 8.10を選択できる時代の記事ですが、Node.js 12.xと読み替えても通用します。

参考記事とほぼ同じですが、僕のやった手順を簡単にメモしておきます。

Lambda Layerに登録するモジュールの作成

cmd
$ cd modules
$ npm i chrome-aws-lambda puppeteer-core

modulesを丸ごとzipしてmodules.zipを作成

コメント 2020-04-26 233309.png

Lambda Layer作成

このステップはほぼ参考記事のまんまです。

AWSコンソールからLambda Layerを開く

コメント 2020-04-26 233955.png

レイヤー作成(npmモジュール群)

コメント 2020-04-26 233955-2.png

image.png

  • 名前:任意
  • .zipファイルをアップロード:先ほど作成したmodules.zipを選択
  • 互換性のあるランタイム:Node.js 12.x
  • 作成ボタン押下

日本語フォントを登録する

Lambda Layerに登録するための日本語フォントをローカルにダウンロードします。
僕の場合は、以前取得していた日本語フォントファイルが手元にあったので、詳細な手順は割愛します。
IPAのサイトからダウンロードしたり、適当な記事を参考に各自調達してください。

取得したフォントファイルを.fonts配下に格納し、エクスプローラから.fontsフォルダごとzipして.fonts.zipを作成します。
image.png

レイヤー作成(日本語フォント)

再びAWSコンソールからレイヤー作成を行います。
コメント 2020-04-26 233955-2.png

image.png

  • 名前:任意
  • zipファイルをアップロード:先ほど作成した.fonts.zipを選択
  • 互換性のあるランタイム:Node.js 12.x

Lambda関数作成

このステップもほぼ参考記事のまんまです。

AWSコンソールからLambda 関数を開く

image.png

関数作成

image.png
image.png

  • 関数名:任意
  • ランタイム:Node.js 12.x
  • 実行ロール:後で編集するので、作成時は適当に。
  • 「関数の作成」を押下
レイヤー登録

デザイナービューでLayersを選択する
image.png

「レイヤーの追加」ボタンを押下
image.png

レイヤーを追加する
image.png

追加したいレイヤーとバージョンを選択し、「追加」ボタンを押下する。
この手順を繰り返して、先ほど作成した2つのレイヤーを追加する。

index.jsの編集

デザイナービューでLambda関数を選択し、メイン処理を記述する。
image.png

index.js
/* 日本語フォントが入っている.fontsを読み込ませるためにHOMEを設定する */process.env['HOME']="/opt";// Layerの内容は/optにあるconstAWS=require('aws-sdk');constchromium=require('chrome-aws-lambda');constpuppeteer=require('puppeteer-core');// パラメータ定義constSAVE_BUCKET_NAME='キャプチャ保存先のバケット名'constoperations=[{method:'goto',args:['https://www.yahoo.co.jp/']},{method:'waitFor',args:[1000]}]/* ユーティリティ関数 */// operationsに従ってブラウザ操作。clickやwaitFor時にキャプチャを取得constexecOperations=asyncfunction(page,operations,result,jpgBuf){for(constopofoperations){console.log(`${op.method} (${op.args[0]}${op.args.length>1?" ,"+op.args[1]:""})`)if(op.method==='click'){jpgBuf.push(awaitpage.screenshot({fullPage:true,type:'jpeg'}));}awaitpage[op.method](...op.args)if(op.method==='waitFor'){jpgBuf.push(awaitpage.screenshot({fullPage:true,type:'jpeg'}));}}}// S3にキャプチャを保存constsaveJpg=async(jpgBuf)=>{consts3=newAWS.S3();constnow=newDate();now.setHours(now.getHours()+9);constnowYMD=now.getFullYear()+(now.getMonth()+1+'').padStart(2,'0')+(now.getDate()+'').padStart(2,'0')constnowHMS=(now.getHours()+'').padStart(2,'0')+(now.getMinutes()+'').padStart(2,'0')+(now.getSeconds()+'').padStart(2,'0');for(constidxinjpgBuf){constfileName='screenshots/'+nowYMD+'/'+nowHMS+'_'+('0000'+idx).slice(-4)+'.jpg';lets3Param={Bucket:SAVE_BUCKET_NAME,Key:fileName,Body:jpgBuf[idx]};awaits3.putObject(s3Param).promise();}}// メイン処理exports.handler=async(event,context)=>{letbrowser=null;constresult={}constjpgBuf=[]try{// 初期処理browser=awaitpuppeteer.launch({args:chromium.args.concat(['--lang=ja']),defaultViewport:chromium.defaultViewport,executablePath:awaitchromium.executablePath,headless:chromium.headless,});letpage=awaitbrowser.newPage();awaitpage.setExtraHTTPHeaders({'Accept-Language':'ja-JP'});// ブラウザ操作awaitexecOperations(page,operations,result,jpgBuf)// 取得したキャプチャをS3に保存awaitsaveJpg(jpgBuf)}catch(error){returncontext.fail(error);}finally{if(browser!==null){awaitbrowser.close();}}returncontext.succeed(result);};
Lambdaの設定を編集する

メモリとタイムアウトはデフォルトだと少なすぎる/短すぎるので、適当に増やす。
image.png

Lambda関数にアタッチされているIAMロールにS3書き込み権限を付与する

Lambda関数の基本設定の「編集」ボタンを押下してLambdaにアタッチされているIAMロールを確認する。
image.png
「IAMコンソールでxxxxxロールを表示します」のリンクからIAMロールを編集し、S3書き込み権限を付与する。
image.png

S3バケットを作成する

キャプチャ保存用のS3バケットを作成する。
Lambda関数のindex.js の SAVE_BUCKET_NAME に作成したバケット名を設定する。

Lambda関数の実行

Lambda関数の「テスト」を押下する。(初回はテストオブジェクトの定義が必要だが、適当でOK。)
image.png

結果

日本語を含むページのキャプチャが文字化けすることなく取得できました。
image.png


Viewing all articles
Browse latest Browse all 9086

Latest Images

Trending Articles