雲のメモ帳

猫とクラウドと旅行が好きなインフラエンジニアです。 日々の調べたことや興味が持ったことをこのブログにアウトプットします。

AWS LambdaとLINE APIを使って商品情報チェックBotを作ってみた

これはなに?

ECサイト上ですぐに売り切れてしまう商品が再販されたときにLINEに通知する仕組みをLambdaを使って簡単に作ってみたので、簡単なメモです。

※注意
処理の内容にスクレイピングを含んでいます。ECサイトに影響がないようにrobots.txtや規約情報を確認して、実施する際は自己責任で実施してください。

スクレイピングする際の注意点。
スクレイピング、クローリングする時の注意点 — Pythonオンライン学習サービス PyQ(パイキュー)ドキュメント

作ったもの

Lambdaを使って定期的に該当のWEBサイトをスクレイピングし商品の販売有無をチェックします。もし、商品が販売されている場合は、販売されている商品情報(商品名、価格、URL)をLINE APIを使ってLINEグループに通知します。

  1. Event Bridgeより、定期的にLambdaを起動。
  2. Lambda内の処理
    • 該当のWEBサイトをスクレイピング。商品情報をDataframeに格納。
    • Dataframeをクエリし、購入したい商品の存在有無チェック
    • (商品が存在していた場合) LINE APIでLINEグループに、商品情報を通知
    • (商品が存在していなかった場合) 処理終了

f:id:ykoomaru:20220214230842p:plain

構成要素

商品情報を監視したいサイトごとに作り方が変わるのでソースは乗せませんが、実装に必要な要素を一部抜粋して記載します。

① スクレイピング

スクレイピングにはBeautifulSoupを利用しています。
サイトによってHTMLの構造が異なるのであくまで参考となりますが、5行目のクラス名と部分を自身が取得したい情報を持つクラスを指定する感じです。

headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36"}
html = requests.get(url,headers=headers)
soup = BeautifulSoup(html.content, 'html.parser')
contents = soup.find_all(class_="<クラス名>")

今回作ったものでは、商品名、価格、商品URL、販売状況をPandasのDataframeに一旦格納しました。
格納した結果、売り切れフラグがFalseになる行が1行以上ある場合、その行の情報をLINEに通知しています。

#--------------------
# 発売中の商品があるかチェックする関数
#--------------------

def check_new_products(df):
    if len(df.query('売り切れフラグ == False')) !=0:
        return True
    else:
        return False

DFの結果は以下のような形です。
f:id:ykoomaru:20220214224638p:plain

②LINE API

LINE APIを使うまでに色々と設定が必要なのですが、過去のブログで簡単にまとめていますので参考にしていただけますと幸いです。
www.cloudnotes.tech

Lambda上でPandasやLINE APIを利用するために、今回はLambdaのLayerを利用したので、以下参考にしてください。

www.cloudnotes.tech

LINE通知の部分を参考までに抜粋

#--------------------
# LINEにメッセージを送信する関数
#--------------------

def push_message(df):
    # Line API利用に必要な変数設定
    user_id = 'XXXXXXXXX'
    channel_access_token = 'YYYYYYYYYYYY'
    line_bot_api = LineBotApi(channel_access_token)

    # メッセージの生成
    message='新商品が入荷されています!\n'
    
    for product_name, price,url in zip(df.query('売り切れフラグ == False')['商品名'], df.query('売り切れフラグ == False')['価格'], df.query('売り切れフラグ == False')['URL']):
        print(product_name,price,url)
        message= "{}\n* {} | {} | {}\n".format(message,str(product_name),str(price),str(url))
        
    messages = TextSendMessage(text=message)
    # line_bot_api.push_message(user_id, messages=messages)
    
    line_bot_api.broadcast(messages=messages)

初めpush_messageを利用していたのですが、自分にしか通知できていなかったので、broadcastに変更しグループに参加しているメンバー全員に通知するよう修正しました。

通知イメージ

LINEへの通知は以下のようなイメージとなります。
f:id:ykoomaru:20220214225842p:plain

LINE APIでは装飾したりする機能があるので、もう少しおしゃれに通知もできそうですね。
developers.line.biz

最後に

よくTwitterとかで商品の通知Botとかを見かけるので気になっていたのですが、思ったよりも簡単に通知Botを作成することができました。実行時間が短いのでLambdaもほぼ無料で使えますし、LINE APIも無料で使えるのでお財布にも優しい実装となっています。
HPの構造が変わると作り直しになるので、そこをうまいこと吸収できる方法がないか模索中。