【Python/Selenium】楽天競馬の百円入金を自動化してみた

# 目的
**楽天ハッピープログラムのランクを簡単にあげよう**
**Python/Seleniumの自動化を始めてみよう**

## Github

御託は良いから、コードを早く見せろという方のためにGithubリポジトリを用意しました。
スター待ってます🙌

https://github.com/wadakatu/rakuten_horse

## 前提条件
1. Google Chromeをインストールしている
2. Google Chromeのバージョンに応じた、ChromeDriverを[ダウンロード](https://chromedriver.chromium.org/downloads)している
3. Selenium、pythonの基礎知識がある

python/Seleniumが初めてという方は、下記の記事がおすすめ
https://qiita.com/memakura/items/20a02161fa7e18d8a693
https://qiita.com/mastar_3104/items/0a1ce2bfa1d29287bc35

## pythonコード


### config.py

このファイルには、各種クレデンシャル情報が格納されています。（@Herb 様から、[頂いた案](https://qiita.com/wadakatu/items/867640340564e571e8f7#comment-2eec4aeb440a53c32f9f)です。）
各々の情報に書き換えてください。

```python:config.py
CONFIG = {
    'mailAddress': 'test@gmail.com',　#ログインメールアドレス
    'password': 'test_password',　#ログインパスワード 
    'pinCode': 1111, #楽天銀行のPIN番号
    'amountOfMoney': 100, #入金金額
    'slack': 'https://hooks.slack.com/services/test_token', #Incoming WebhookのURL
    'slackUser': '12345ABCDE' #DM送信先のユーザーID（slack）
}
```

### slack.py

slackアプリの[Incoming Webhook](https://api.slack.com/messaging/webhooks)を使用してconfig.pyで指定したユーザーにDMを送ります。
config.pyの**slack**にURLを指定していない場合は、特に何も送信されません。

```python:slack.py
from config import CONFIG
import requests
import json
import traceback

class Slack:

    SLACK = CONFIG['slack']
    USER = CONFIG['slackUser']

    def start(self):
        requests.post(self.SLACK, data=json.dumps({
            "text": "<@" + self.USER + ">" + " " + '自動入金開始'
        }))

    def finish(self):
        requests.post(self.SLACK, data=json.dumps({
            "text": "<@" + self.USER + ">" + " " + '自動入金終了'
        }))

    def error(self):
        requests.post(self.SLACK, data=json.dumps({
            "text": "<@" + self.USER + ">" + " " + 'エラー発生！:' + traceback.format_exc()
        }))
```

### login.py

楽天競馬サイトのログインを担うクラスです。

```python:login.py
from selenium.webdriver.common.keys import Keys
from config import CONFIG
from selenium import webdriver

class Login:

    MAIL = CONFIG['mailAddress']
    PASSWORD = CONFIG['password']

    def loginFlow(self, driver: webdriver):
        driver.find_element_by_class_name("siteheader_actionlist_btn").click()
        driver.switch_to.window(driver.window_handles[1])
        driver.maximize_window()

        userid = driver.find_element_by_name("u")
        userid.send_keys(self.MAIL)
        password = driver.find_element_by_name("p")
        password.send_keys(self.PASSWORD)
        password.send_keys(Keys.RETURN)
```

### action.py

楽天競馬サイトで、暗証番号・金額の入力を担うクラスです。

```python:action.py
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from config import CONFIG

class Action:
  
    PINCODE = CONFIG['pinCode']
    MONEY = CONFIG['amountOfMoney']

    def inputMoney(self, driver: webdriver):
        insert_money = driver.find_element_by_id("dialogDepositingInputPrice")
        insert_money.send_keys(self.MONEY)
        confirm = driver.find_element_by_id("dialogDepositingConfirm")
        confirm.send_keys(Keys.RETURN)

    def inputPinCode(self, driver: webdriver):
        pincode = driver.find_element_by_id("dialogDepositingConfirmPin")
        pincode.send_keys(self.PINCODE)
        complete_insert = driver.find_element_by_id("dialogDepositingComplete")
        complete_insert.send_keys(Keys.RETURN)
```

### main.py

自動化の処理の肝となる部分です。
ここで、slack.py, login.py, action.pyの処理をまとめて呼び出しています。
これを動かせば、とりあえず自動入金が完了します。

```python:main.py
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from login import Login
from action import Action
from slack import Slack
import time

class Main:
    
  def main():
      login = Login()
      action = Action()
      slack = Slack()
      
      try:
          options = Options()
          options.add_argument('--headless')
          
          slack.start()

          # webdriver準備
          driver = webdriver.Chrome("./chromedriver")
          # 楽天競馬にアクセス
          driver.get("https://keiba.rakuten.co.jp/?l-id=top_logo")

          time.sleep(5)

          # モーダルが表示された場合は、モーダルを削除する 
          if len(driver.find_elements_by_xpath("/html/body/section/div[2]/div")):
              pop = driver.find_element_by_xpath("/html/body/section/div[2]/div")
              pop.click()
          
          # 楽天競馬にログインする
          login.loginFlow(driver)

          driver.find_element_by_class_name("modal").click()
          time.sleep(3)

          # 入金額を決める
          action.inputMoney(driver)
          time.sleep(5)

          # 暗証番号を入力し、入金を確定
          action.inputPinCode(driver)
          time.sleep(3)
          
      except Exception as e:
          slack.error()
      finally:
          slack.finish()
          driver.quit()

  if __name__ == "__main__":
      main()
```

## 注意点（Chrome Driver)
ChromeDriverの保存場所は、上記pythonファイルと同じディレクトリ内にしてください。

急に自動化が動かなくなることがありますが、**十中八九ChromeDriverのバージョンが古い**ことが原因です。
昨日まで動いてたのに、急にエラーが出た場合には、ChromeのバージョンとChromeDriverのバージョンが一致しているか、まず見てあげて下さい。

## ハッピープログラムとは

**ハッピープログラム**って何？美味しいの？っていう人のために、
参考画像貼り付けておきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/838340/a02f14e4-ee5a-ad83-f48d-487b6b664660.png)

簡単にいうと、**ランク**が上がれば上がるほど美味しい思いができるよというものです。

この**ランク**の上げ方にも、色々あります。
例えば・・・
1. たくさんのお金を銀行に預ける。
2. 給与の受け取りを楽天銀行にする。
3. 他の銀行へ振り込みをたくさんする。 etc...

私は、正直お金もたくさん無いですし　*(早くボーナス欲しい・・・)*
　　　給与の受け取りはみ○ほ銀行ですし　*(み○ほのATM近くにない・・・)*
　　　他行への振り込みは、できるだけしたくない人間です。*(手数料高すぎ・・・)*

同じように思う方は多いのではないでしょうか？
安心してください。

そんなあなたにぴったりなランクの上げ方があります。

## **楽天競馬に毎日１００円だけ入金する。**

### ！！！！！？？？？？？

## そうです、毎日１回、楽天競馬に１００円入金するだけで良いのです。
それを３０日続ければ、自動で**スーパーVIP**です。

---

---2021/2/7 更新---
これまでは、入金すれば1日１ポイント(１ヶ月で３０ポイント)として、ハッピープログラムのランクが上がりました。
しかし、これからは、(正確には2020/12/26から)、月に３ポイントまでしか加算されなくなりました。
楽天銀行にはがっかりです。。

---

#### しかも、その１００円は無傷であなたの元へ帰ってきます（お馬さんに賭けない限り)

最高ですよね。
でも、手動で楽天競馬のアプリを開いて、メールアドレス打ち込んで、
パスワード打ち込んで、PINコード打ち込んで、って結構めんどくさいです。

そんな時に、**python,seleniumを使った自動化**が力を発揮します。

## 更新履歴

### 2020/12/2
・コード１つ１つの動きについて追記しました！

### 2021/11/13
・コードを複数ファイルに分割しました。
・[Github](https://chromedriver.chromium.org/downloads)のリポジトリを追加