ポケカの入荷情報を教えてくれるLINEbotを作りました

一昔前に書いた記事です。

皆様はポケモンカードゲームやってますでしょうか？僕は1月に友人に勧められて始めました．ポケカ初めて1か月くらいたったのですが，分かったことがあります．

**ポケモンカードは買えない！**

人気すぎるんですね．この間でたばかりの一撃マスター・連撃マスターに加え，誰しもが買いたいであろうシャイニースターV，他にも人気の過去の商品が多数あります．もちろん，転売ヤーから高い値段で買うことはできますがそんなことはしたくない！そう思い，ポケモンセンターオンラインで入荷したらLINEで通知が来るようなbotを作成することにしました．
Pythonの歴はポケカよりも短く，今月始めたばかりなので稚拙なプログラムになっているとは思うのですがアドバイス等あればぜひお願いします．

# 環境
- Raspberry Pi 3(Windows10)
- Raspbian

# 環境設定
このプログラムでは，Raspberry Pi(以下ラズパイ)を用いて入荷しているかどうかのプログラムを毎分動作させることで目的を達成させています．Windowsでももちろん起動させ続ければ可能ですが，ずっとPCをつけておく必要があります．以下はラズパイで動作させることを前提に話していきますが，基本Windowsでも可能です．

#ライブラリのインストール
今回のプログラムで必要なライブラリをインストールします．Windowsの方はPythonの環境構築をまずしてもらい，その後これらのライブラリをインストールしてください．どちらも場合でも，コマンドプロンプトに以下のものを順々に入力するだけです．Winの方は$は>>だと思ってください．

```
$ pip3 install line-bot-sdk
$ pip3 install schedule
$ pip3 install requests
$ pip3 install beautifulsoup4
```

他にも必要なライブラリがあるかもしれませんが，基本installの後に入れたいライブラリ名(line-bot-sdkとか)を入力するだけです．

#LINEの設定
[こちら](https://qiita.com/nkjm/items/38808bbc97d6927837cd)の記事の最初の章を参考にLINEDevelopersに登録し，Messaging API(要はbot)を作成します．そしてそのアクセストークンというものをメモしておいてください．

![スクリーンショット 2021-02-25 15.50.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011513/bc5ac21e-2eac-99ff-6635-636e3d4c9065.png)

次に，そのAPIを入手するページから上記画像にあるチャンネルの基本設定というページに飛びます．そこにあるあなたのユーザーIDというのもメモしておきます．これはあなたが普段使用しているLINEのIDで，このIDあてに通知が来るように設定します．

#プログラム
``` pokemon.py
import requests
import re
from bs4 import BeautifulSoup
from linebot import LineBotApi
from linebot.models import TextSendMessage
from linebot.exceptions import LineBotApiError
import schedule
import time
import datetime


def LINEloop():
    LINE_CHANNEL_ACCESS_TOKEN = "チャンネルトークン"
    line_bot_api = LineBotApi(LINE_CHANNEL_ACCESS_TOKEN)
    LINE_USER_ID = "LINEユーザーID"
   
    # 欲しいものの商品名
    card = ["シャイニースターV" , "TAG TEAM GX BOX"]

    result_str1 = "予約受付中"
    result_str2 = "在庫あるよ！"

    # 欲しいもののURL
    pokemon_url = [
        "https://www.pokemoncenter-online.com/?p_cd=4521329313405",
        "https://www.pokemoncenter-online.com/?p_cd=4521329266541"

            ]
    

    dt_now = datetime.datetime.now()
    print(dt_now.minute)
    if 8 < dt_now.hour < 21:
        if dt_now.minute == 0:
            line_bot_api.push_message(LINE_USER_ID, TextSendMessage(text="動作確認 at " + str(dt_now.hour) + ":" + str(dt_now.minute) + ":" + str(dt_now.second)))

    for i in range(len(pokemon_url)):
        data = requests.get(pokemon_url[i], headers = my_header)
        data.encoding = data.apparent_encoding
        data = data.text
        soup = BeautifulSoup(data, "html.parser")
        detail = soup.find("table",class_="no_size")
        detailstr = str(detail)

        if "soldout" in detailstr:
            1
        elif "yoyaku" in detailstr:
                line_bot_api.push_message(LINE_USER_ID, TextSendMessage(text=card[i]+result_str1))
        elif "add_cart_btn":
                line_bot_api.push_message(LINE_USER_ID, TextSendMessage(text=card[i]+result_str2))
        

    
def main():
    LINEloop()


if __name__ == "__main__":
    schedule.every(1).minutes.do(main)
while True:
    schedule.run_pending()
```

#利用方法
まず，LINEのアクセストークンとユーザーIDを所定の箇所に入力します．入力後は""でそれぞれが囲われている状態にしておいてください．
次に，欲しいもののURLを取得しておきます．今回はシャイニースターVとTAG TEAM GXのBOXにしています．
取得したら，欲しいもののURLという部分に""で囲って入力し，複数ある場合は,で区切って複数入力していきます．今回は2つですが，何個でも可能です．
そして，欲しいものの商品名の部分も変更します．わかるような名称を""で囲い入力します．ただし，この入力順はURLを入力した順番と一致させてください．
そうしましたら，いよいよ動作確認です．動作確認をする際は，pokemon.pyの最後の部分

```
if __name__ == "__main__":
    schedule.every(1).minutes.do(main)
while True:
    schedule.run_pending()
```
を

```
if __name__ == "__main__":
    main()
```
にすることで，1度のみ動作をさせることが可能になります．ここでエラーをはかず現在の分数がでれば動作確認完了です．エラーは調べてもらうと多分出てくるんでそれを見て対処してください．どうしてもわからなかったらコメントしてくだされば一緒に考えます(対処はできないかも)．
ちゃんと動作しているかを確認するために8～21時の毎時0分に動作チェックのLINEが来ますが，『うっせえわ』という方は

```
    if 8 < dt_now.hour < 21:
        if dt_now.minute == 0:
            line_bot_api.push_message(LINE_USER_ID, TextSendMessage(text="動作確認 at " + str(dt_now.hour) + ":" + str(dt_now.minute) + ":" + str(dt_now.second)))
```
の部分を消せば来なくなります．8，21の部分を変えれば来る時間帯の変化も可能で，0を変えれば来る分数も変更可能です．

# 解説
解説というほどちゃんと説明する気もないのですが，大まかな流れだけ書いておきます．動作すればいいという方は読まなくていいです．

1. 対象のURLからrequests，BeautifulSoup4を用いてカートに入れるとかが書いてある部分のHTMLを取得
2. 対象のHTMLは画像データを含むのでその画像データのタイトルで判断する．"soldout"が含まれていたら売り切れ，"yoyaku"が含まれていたら予約受付中，"add_cart_btn"と含まれていたら在庫あり．ただし，予約受付中の時も"add_cart_btn"は含まれるのでこの順でなければ判断できない．
3. 予約受付中もしくは在庫ありだった場合，line_bot_apiを用いてメッセージを送る

この一連を毎分schedule関数を用いて実行する，といったところです．取得するHTMLをいじればAmazonや他のサイトでも価格を監視したりできると思います，

# おわりに
ポケカが欲しすぎて初めてPythonに触れましたが，Cを授業でちょっと触れたことのないプログラミング初心者でもQiitaを参考にしたり既存のライブラリを利用すればある程度できて便利だなと感じました．HTMLの取得部分は正直あまり理解できていないのでそこをどうにかするのと，あとはscheduleで毎分実行するというのはだいぶゴリ押しなんだろうというのはプログラミング初心者の私でもわかるのでそこももっといい手段があれば変えたいです．いい方法あれば教えてください．
なんであれ，達成感だけはあったのでやってみてよかったです．ラズパイもこのためだけに買って，初めて使いました．ラズパイとPCキーボードとマウス1つでどうにか抜き差しなしで共有できないんですかね？教えてください．
ちなみにこれ作ってからずっと動作させてるけど肝心の入荷はまだないです．