Webサイトの状況を監視するためのスクリプトを動かしたいというシチュエーションが発生することがあります。典型的な例としてECサイトの在庫監視などがあると思います。Nintendo Switchの在庫状況を監視して通知するスクリプトを動かしている人もいるもいるのではないでしょうか。*1
在庫確認のようなシチュエーションでは常時起動しているPC、すなわちサーバに相当するものを用意しなければなりません。VPSを借りる人も多いと思いますが、スクリプトを動かすだけに使用するには少々オーバースペックです。
そこで今回はAWS Lamdaを使って安価にサーバレスでサイトの在庫状況を監視するシステムを構築します。例としてNintendo Switchの在庫状況を通知するシステムを作ります。
おそらく無料枠内で収まると思いますが、無料枠を超えたとしてもAWS Lambda自体がかなり安価なので、VPSを借りるよりも安価になることが多いはずです。
構成
AWS Lambda上で実行することができる言語の一つ、Pythonでスクリプトを記述します。スクリプトの中に通知をとばす処理を記述しておきます。今回はSlackに通知します。
その後スクリプトを使用するライブラリを含めてアップロードを行い、Cloud Watchをトリガーにして一定間隔でAWS Lambdaを実行します。
構成図は以下のようになります。
スクリプト
スクレイピングが明示的に禁止されているサイトは実行しないでください。*2
最初に使用するライブラリをpip install
でインストールします。
pip install requests -t . pip install beautifulsoup4 -t . pip install slackweb -t .
AWS Lambdaではライブラリを含めたフォルダをzipでまとめてアップロードする必要があるので、-t
オプションでカレントディレクトリを指定しています。
次に実行したいスクリプトを書きます。
import requests import slackweb from bs4 import BeautifulSoup def buy_bot(event, context): # Camouflage User Agent user_agent = { "User-Agent": "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; NP06; rv:11.0) like Gecko" } # merchandise URLs # Example: Checking Joshin switch stock joshin_url = [ "http://joshinweb.jp/game/40519/4902370535716.html", # Neon Blue "http://joshinweb.jp/game/40519/4902370535709.html", # Gray ] # Incoming Webhook API key slack = slackweb.Slack(url="INCOMING WEBHOOKS API KEY ") # slack.notify(text="From Python to Slack") # DEBUG # Joshinサイトの監視 for url in joshin_url: html = requests.get(url, headers=user_agent) html.encoding = html.apparent_encoding html = html.text soup = BeautifulSoup(html, "html.parser") detail = soup.find("form",{"name":"cart_button"}).text if not ("販売休止中です" in detail): # Check stock messages slack.notify(text="Joshin: Nintendo Switch is available now. \n" + url)
Beautiful Soupでスクレイピングを行い、販売が休止していないときにIncoming WebhooksのAPIを使って在庫が存在していることをSlackのチャンネルへ通知します。Incoming Webhooksの仕様は公式ドキュメントを参考にしてください。
また関数がdef buy_bot(event, context)
のように宣言されていますが、このevent
とcontext
はAWS Lambdaのイベントをハンドルするために必要な引数となります。
AWS Lambdaの設定
ハンドラ
スクリプトをzipで圧縮し、AWS Lambda上にアップロードします。アップロードが終わったら関数がハンドラを受け取れるように設定を変更します。
ハンドラは
<ファイル名><メソッド名>
で記述します。例で使用したスクリプトであればbuybot.buy_bot
となります。ロールはlambda_exec_role
にします。
タイムアウトとリソース
デフォルトの設定ではリソースが足りずにタイムアウトしてしまうので、設定でメモリを増やしてタイムアウトの時間を長くします。
なおAWS Lambdaはメモリを増やすことでCPUの性能が増加する仕様になっています。
トリガー
次にAWS Lambdaを動かすためのトリガーを設定します。Lambdaを一定間隔で実行するためにCloudWatch Eventsを使用します。ここではおなじみのcron式を使うことができます。
スクレイピングを行う場合、サイトに迷惑がかからないように十分な間隔を開けましょう。
今回のスクリプトは1分間に1回だけ実行するようにしました。次のようなcron式になります。
cron(*/1 * * * *)
まとめ
とても簡単にサーバレスな監視システムを作ることができました。EC2やVPSなどを使って1からシステムを作る場合はサーバーの構築などを行わないといけないので、それに比べると気軽に動かすことができていい感じですね。
参考
switchが入荷したらLINEで通知するプログラムを作った - Qiita
Amazon Web Services クラウドネイティブ・アプリケーション開発技法 一番大切な知識と技術が身につく (Informatics&IDEA)
- 作者: NRIネットコム株式会社,佐々木拓郎,佐藤瞬,石川修,高柳怜士,佐藤雄也,岸本勇貴
- 出版社/メーカー: SBクリエイティブ
- 発売日: 2016/04/20
- メディア: 単行本
- この商品を含むブログ (1件) を見る
*1:ちなみに私はSwitchをまだ持っていません。欲しいです。
https://www.amazon.co.jp/gp/help/customer/display.html?nodeId=201909000