AWS Lambdaを使ってAmazonコインを安く買う
先日AWS Lambdaを初めて使ったので忘備録を兼ねて書きます
今回書いたコードはここで見れます
Amazonコインの価格変動
1年ぐらい前からHearthstoneというデジタルカードゲームにハマっています。 Hearthstoneは課金でカードパックを買えるのですが、Amazonアプリストア版のAndroidアプリを使用すると、Amazonコインでの支払いが可能で、クレジットカードで直接買うよりより少し安くなります。
そんなAmazonコインですが、実は日々値段が変動しているみたいです。
Amazonコインの価格の変動・推移を調べてみる2018-2 | JJゃもの部屋 \(^o^)/ 破滅に向かって2011
↑の記事を見た感じ、10000コインが8100円のときにまとめ買いしておくとおトクなようです。
Amazonコインが安い日を見逃さないために、今回はpythonでwebスクレイピングを行いコインの価格を自動で追跡するスクリプトを作成しました。また、そのスクリプトをAWS Lambdaで自動化しました。
Amazonコインの価格を自動で取得する
PythonでAmazonコインの価格を追うスクリプトを書きました。
まず、venv
を用いて仮想環境を作成し、必要となるライブラリをインストールします。
$ python3 -m venv amazoncoin $ cd amazoncoin $ source bin/activate # bash zsh等の場合 $ source bin/activate.fish # fish shellの場合 (amazoncoin)$ pip install requests beautifulsoup4 (amazoncoin)$ pip freeze > requirements.txt #必要なライブラリを書き出しておく(あとで使う)
10000Amazonコインの販売ページは https://www.amazon.co.jp/dp/B00KQVXDW0/ であり、価格はid=priceblock_ourprice
のspan
タグに記載されているので、以下のようなスクリプトで価格を取得できます。*1
import requests from bs4 import BeautifulSoup def find_price(): coin_url = "https://www.amazon.co.jp/dp/B00KQVXDW0/" resp = requests.get(coin_url, timeout=1) soup = BeautifulSoup(resp.text, 'html.parser') target = soup.findAll('span',{'id':"priceblock_ourprice"}) return int(target[0].text[2:].replace(',', '')) print(find_price())#=> 8100など
価格をLine Notifyで通知する
次に、取得した価格をLine Notifyを使って自分のLINEアカウントに通知することにしました。 [参考] https://qiita.com/hiro-abe/items/e42f857bd6b40bc178a3
下準備として、LINE Notifyのwebページでアクセストークンを取得し、環境変数LINE_NOTIFY_TOKEN
に値を書き入れておきます。
$ export LINE_NOTIFY_TOKEN=XXXXXXXXX # bash zsh等の場合 $ set -x LINE_NOTIFY_TOKEN XXXXXXXXX # fishの場合
そして、以下のスクリプトを実行するとLINEに通知が届きます。
import requests from bs4 import BeautifulSoup import os def lambda_handler(event, context): output_url = "https://notify-api.line.me/api/notify" token = os.getenv("LINE_NOTIFY_TOKEN", "") price = find_price() headers = {"Authorization" : "Bearer "+ token} message = '現在10000 Amazonコインは' + str(price) + '円です' payload = {"message" : message} r = requests.post(output_url ,headers = headers ,params=payload) return 'Notify Amazon Coin Price is running' lambda_handler(None, None) # => LINEの指定したトークルームに通知が来る
これで、script.lambda_handler関数を実行することで、Amazonコインの価格がLINEに届くようになりました。
AWS Lambdaで毎日自動で動かす
上記のスクリプトをASW Lambdaを用いて自動化します。 Lambdaを用いて自動化します。今回は毎朝8時に実行させるようにします。
スクリプトのパッケージ化
最初に作成したスクリプトをzipにまとめます。Lambdaは使用するスクリプトをzip形式でアップロードする方式になっているためです。*2 このとき注意しなければならないのは、標準ライブラリ以外のライブラリも一緒にzipにまとめる必要がある点です。
デプロイ用のディレクトリを作成し、そこに今回のスクリプトとライブラリをすべて設置し、zipにまとめることにします。
mkdir deploy #デプロイ用ディレクトリを作成 cp script.py deploy #今回作ったスクリプトをデプロイ用ディレクトリにコピー pip3 install -r requirements.txt -t deploy/ #-tオプションでデプロイ用ディレクトリにライブラリをインストール cd deploy/ zip -r package.zip * #パッケージを作成 mv package.zip ../
これで、作業ディレクトリにpackage.zipが作成されます。 動作確認として、以下のようなコマンドを実行したらスクリプトが正しく動作することを確認してください。
(amazoncoin) $ deactivate #仮想環境が有効になっている場合のみ $ cd deploy/ $ python3 -c "import script;script.lambda_handler(None, None)" # > Notify Amazon Coin Price is running # (LINEに通知が来る)
AWS Lambdaの設定
パッケージが完成したので、早速Lambdaのセッティングをしてみます。
まず、Lambdaの管理ページから新しい関数を作成します。 ロールは「テンプレートから新しいロールを作成」を選択し、「Basic Edge Lambdaアクセス権限」を使用します。他は適当に入力してかまいません。
次に、先程作成したpackage.zipをLambdaにアップロードします。
このとき、ハンドラには[pythonのファイル名].lambda_handler
を指定します。
そして、環境変数の欄にLINE Notifyのアクセストークンを入力します。
最後にタイムアウトの値を少し大きめの値に変更しておきます。*3メモリは最小の128mbで足りるのでデフォルトのままでかまいません。
イベントタイミングの指定
次に通知が来るタイミングを指定します。
トリガーにCloudWatch Eventsを指定します。
ルール名と説明は適当に埋め、ルールタイプを「スケジュール式」、
スケジュール式をcron(0 23 * * ? *)
を指定します。
これで毎日グリニッジ標準時の23時、つまり日本時間の8時にスクリプトが実行されるようになりました。
おわりに
今回はpythonを用いてwebスクレイピングと、AWS Lambdaによる自動化を行いました。
今回、個人的につまずいた点は以下のとおりです。
- ライブラリをzipに含めないとライブラリの関数が使えない点*4
- イベントのトリガーに何を選べばいいのかわからない点
今後の課題として、価格がn円以下のときのみ通知を流すようにしたり、TwitterやDiscordに自動投稿させたりなんかをやりたいと思っています。
今回のプロジェクトはこちらのリポジトリで管理してあります。よかったらforkしてみてください。また、改善点などあればissueに書いてくださると助かります。
2019/01/07 追記
このアプリはしばらく前から放置しており、コードが古くなっています。 urllib3 v.1.23 及び requests v2.20.0 は脆弱性が発見されているようなので、requirements.txtをそのままコピペしないようご注意ください。