1
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

電気使用量を毎日LINE通知!AWS Lambda × Seleniumで自動化 ⚡

Last updated at Posted at 2024-06-09

🎯 目的

最近、電気代がどんどん高くなっていますよね?
毎日、サイトにログインして前日の電気使用量を確認するのが日課になっていましたが、正直面倒くさい…。🤦‍♂️

そこで、バッチ処理で毎日LINEに通知する仕組みを作れば楽になるし、
今まで触れたことのない技術を試せる良い機会になると思い、挑戦してみました!💡

この記事はその備忘録です。🔖


🛠 システム構成

仕組みはシンプルです。以下のようなフローで動作します。

📌 電気使用量をスクレイピングAWS Lambda で取得&保存LINE Notify で通知!

tokyo-gas.png


🔔 LINE Notifyの設定

公式ドキュメントを参考に、サクッと設定完了!

👉 LINE Notifyの設定方法

テスト通知も問題なく成功!🎉

image.png


🏗 Lambda関数の作成

📍 スクレイピング用Lambda

Pythonの selenium を使って東京ガスのサイトから電気使用量を取得します。

from selenium import webdriver
from selenium.webdriver.common.by import By
import time
import datetime
import boto3

driver = webdriver.Chrome()
driver.get('https://members.tokyo-gas.co.jp/')
time.sleep(10)

driver.find_element(By.NAME,"loginId").send_keys("")
driver.find_element(By.NAME,"password").send_keys("")
driver.find_element(By.ID,"submit-btn").click()
time.sleep(5)

driver.get('https://members.tokyo-gas.co.jp/usage?tab=electricity')
time.sleep(5)
driver.find_element(By.ID,"segmented-button-daily").click()
time.sleep(5)

daily = driver.find_element(By.XPATH,'//*[@id="mtg-karte-electricity"]/div/div/div[2]/div/div[1]/div[2]/div[2]/div/div[1]/div').text
print(daily)

driver.quit()

today = datetime.datetime.now()
year_month = today.strftime("%Y%m")
day = today.strftime("%d")
key = f'{year_month}/{day}.txt'

s3 = boto3.client('s3')
s3.put_object(Bucket='tokyo-gas-electricity', Key=key, Body=daily)

💡 ローカルでは動いたのにLambdaではエラー発生…😱

原因を調べたところ、Lambdaの環境には selenium がプリインストールされていないことが判明!

💡 解決策:Docker+ECRを使う!

参考記事

最終的にECR経由でLambdaをデプロイすることで解決!✨

image.png

📍 LINE通知用Lambda

import json
import boto3
import datetime
import urllib.request

def lambda_handler(event, context):
    s3 = boto3.client('s3')
    TOKEN = '作成したアクセストークン'
    api_url = 'https://notify-api.line.me/api/notify'
    BUCKET_NAME = 'tokyo-gas-electricity'
    
    yesterday = datetime.datetime.now() - datetime.timedelta(days=1)
    year = str(yesterday.year)
    month = str(yesterday.month).zfill(2)
    day = str(yesterday.day).zfill(2)
    weekdays_jp = ["", "", "", "", "", "", ""]
    weekday_jp = weekdays_jp[int(yesterday.strftime("%w"))]
    
    object_key = f'{year}/{month}/{day}.txt'
    try:
        response = s3.get_object(Bucket=BUCKET_NAME, Key=object_key)
        file_content = response['Body'].read().decode('utf-8')
        
        message = f"\n{month}/{day}({weekday_jp})の電気使用量は\n{file_content}です!"
        send_line_notify(api_url, TOKEN, message)
        
        return {'statusCode': 200, 'body': 'Message sent successfully'}
    except Exception as e:
        return {'statusCode': 400, 'body': str(e)}

def send_line_notify(api_url, token, message):
    request_headers = {
        'Content-Type': 'application/x-www-form-urlencoded',
        'Authorization': 'Bearer ' + token
    }
    params = {'message': message}
    data = urllib.parse.urlencode(params).encode('ascii')
    req = urllib.request.Request(api_url, headers=request_headers, data=data, method='POST')
    urllib.request.urlopen(req)

✅ 結果

EventBridgeでスケジュール実行した結果…

無事にLINE通知が届いた!🎉

image.png


🔥 まとめ

💡 学びポイント

  1. AWS Lambda で selenium を使うには Docker+ECR が便利!
  2. LINE Notify の設定は簡単にできる!
  3. EventBridge でLambdaを定期実行できる!

🚀 今後のアップデート

  • 電気料金の計算
  • 過去の使用量と比較

今後も改良して、より便利なシステムにしていきたいと思います!💪


最後まで読んでいただき、ありがとうございました!🙌

1
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?