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

AWS LambdaによるスクレイピングでQiita Organizationの最新記事を取得しSlackに通知するBotを作った

$
0
0

Organizationページの「最新の投稿」をAWS Lambda(node.js)でスクレイピングし、新しい投稿の記事のタイトルとURLをSlackに投稿するBotを作ってみました

コードはここに置いてます(大分汚いです)
https://github.com/uji/qiita-organization-scraping/blob/master/app.js

AWS Lambdaの処理の流れ

  1. 「最新の投稿」にある記事をスクレイピングで取得
  2. AWS S3にあるtxtファイルを確認し、Slack未投稿の記事の有無を確認
  3. 未投稿の記事をSlackに投稿
  4. 最新記事のタイトルをtxtファイルでAWS S3に保存

投稿済みの記事を永続化する必要があるのですが、DB使うのは大げさな気がしたのでS3にtxtで保存します

スクレイピング

AWS Lambda 用のchromium chrome-aws-lambdaを使ってスクレイピングしました
Google Cloud Functionsでも使えるっぽいです
puppeteerと使用感はほぼ同じです

.of-ItemLink_header-title classを取ってくると「最新の投稿」の要素を取ってこれます

constchromium=require("chrome-aws-lambda");exports.handler=async(event,context)=>{letbrowser=null;letelems=[];try{browser=awaitchromium.puppeteer.launch({args:chromium.args,defaultViewport:chromium.defaultViewport,executablePath:awaitchromium.executablePath,headless:chromium.headless,});letpage=awaitbrowser.newPage();awaitpage.goto("http://qiita.com/organizations/"+process.env.ORGANIZATION_NAME);constselector=".of-ItemLink_header-title";elems=awaitpage.$$eval(selector,es=>es.map(e=>[e.textContent,e.href]));}catch(error){returncontext.fail(error);}finally{if(browser!==null){awaitbrowser.close();}}returncontext.succeed(elems);};

Slackに通知する

@slack/boltまたは@slack/web-apiでSlack APIを叩き、取得した記事をSlackに投げます
Slack Botでメッセージを送るには、singning secretbot tokenchannel idが必要になります

boltの場合
const{App,ExpressReceiver}=require("@slack/bolt");constreceiver=newExpressReceiver({signingSecret:process.env.SLACK_SIGNING_SECRET});constapp=newApp({token:process.env.SLACK_BOT_TOKEN,receiver:receiver});app.client.chat.postMessage({channel:process.env.SLACK_CHANNEL,text:"message",token:process.env.SLACK_BOT_TOKEN});

S3のテキストファイル読み込み、上書き

投稿済みの記事のタイトルを永続化します
aws-sdkを使うと結構簡単にS3にアクセスできます

読み込み
constAWS=require("aws-sdk");consts3=newAWS.S3({region:"ap-northeast-1"});lets3Params={Bucket:process.env.BACKET_NAME,Key:process.env.FILE_NAME};s3.getObject(s3Params,(err,data)=>{if(err)returncontext.fail(err);elselatest=data.Body.toString();});
上書き
constAWS=require("aws-sdk");consts3=newAWS.S3({region:"ap-northeast-1"});lets3Params={Bucket:process.env.BACKET_NAME,Key:process.env.FILE_NAME,Body:"タイトル"};s3.putObject(s3Params,(err)=>{if(err)returncontext.fail(err);});

AWS Lambdaの設定

ランタイムにnode.jsを指定してLambdaを作成します

まあまあ時間のかかる処理なので、基本設定からメモリ、タイムアウト時間を変更しておきます
メモリは512MB、タイムアウト時間は1分にしました

node_modulesはzipにまとめてLayerに登録します
AWS Lambda レイヤー

AWS Lambdaで動かす

コードをLambdaに書いてテストを実行してみます

スクリーンショット 2020-02-24 0.53.23.png

スクリーンショット 2020-02-23 0.20.28.png

Slackに通知されました

AWS Cloud Watch Eventsで定期実行

AWS LambdaのトリガーにAWS Cloud Watch Eventsを追加して定期実行されるようにします

スクリーンショット 2020-02-24 1.38.12.png

毎朝9時に実行される設定にしました

まとめ

今回はスクレイピングで取得しましたがQiita APIを使ってユーザーごとの最新記事をとる方法もあります
そっちの方が良さそう


Viewing all articles
Browse latest Browse all 9409

Trending Articles