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?

More than 1 year has passed since last update.

【Python】SeleniumでYogiboの半額セールに挑む

Last updated at Posted at 2023-02-26

What

Python Seleniumを利用して2022年11月25日 00:00販売開始予定のYogibo半額セール対象商品を自動購入する
Screen Shot 2022-11-23 at 17.41.13.png

Why

半額セール開始時に多くの人がアクセスするのでものの数秒で売り切れてしまう.
Pythonによって購入までのプロセスを完全に自動化することで,購入できる可能性を飛躍的に向上させる.

Env

  • macOS Big Sur
  • Python 3.9.12
  • Chrome version 107.0.5304.110

Script

下記Pythonスクリプトを作成した
これにより,設定した時刻に自動で商品が購入される
また,購入するYogiboが本当に半額になっているかのチェックもコード内で行っている

yogibo.py
#coding:utf-8
#copyright@shuto.kawabata
from selenium import webdriver
from selenium.webdriver.support.ui import Select
from selenium.webdriver.chrome.options import Options
from time import sleep
import datetime, warnings
warnings.simplefilter('ignore')

# config for login
EMAIL = "taro.gundam@gmail.com"
PASSWORD = "mypassword"

# config for start time
STARTTIME = "2022年11月25日 00:00:00"

# config for credit card
CARDNUMBER = "0000111122223333"
FIRSTNAME = "TARO"
LASTNAME = "RAKUTEN"
EXPIREDMONTH = "03"
EXPIREDYEAR = "23"
SECURITYCODE = "999"

# ChromeDriverの起動
options = Options()
driver = webdriver.Chrome('./chromedriver')
driver.implicitly_wait(10) #最大待機時間10s

# ログイン
driver.get("https://yogibo.jp/mypage/login")
driver.find_element_by_id('login_email').send_keys(EMAIL)
driver.find_element_by_id('login_pass').send_keys(PASSWORD)
driver.find_element_by_xpath('//*[@id="login-input"]/button').click()

prevTime = ""
while True:
    sleep(0.1)

    # 現在時刻の取得
    dt_now = datetime.datetime.now()
    currentTime = dt_now.strftime('%Y年%m月%d日 %H:%M:%S')
    
    if currentTime!=prevTime:
        print(currentTime)

    prevTime = currentTime

    # 販売開始時刻まで待機
    if currentTime == STARTTIME:
        
        # 商品をカートへ入れる
        driver.get("https://yogibo.jp/products/detail/min")
        driver.find_elements_by_tag_name('button')[12].click() #ライトグレー
        driver.find_element_by_xpath('//*[@id="form_cart"]/div[3]/button').click() #購入手続きへボタン

        # 銀行振り込みを選択
        driver.find_element_by_id('shopping_payment_1').click()

        # クレジットカード情報の入力
        #driver.find_element_by_id('gmo_payment_card_no').send_keys(CARDNUMBER)
        #driver.find_element_by_id('gmo_payment_method').send_keys('一括払い')
        #driver.find_element_by_id('gmo_payment_security_code').send_keys(SECURITYCODE)
        #driver.find_element_by_id('gmo_payment_expire_month').send_keys(EXPIREDMONTH)
        #driver.find_element_by_id('gmo_payment_expire_year').send_keys(EXPIREDYEAR)
        #driver.find_element_by_id('gmo_payment_card_name1').send_keys(FIRSTNAME)
        #driver.find_element_by_id('gmo_payment_card_name2').send_keys(LASTNAME)

        # きちんと半額になってるのを確認してから購入確定ボタンをプッシュ
        if  driver.find_element_by_class_name('item-sum').text == "小計:8,900円":
            # 購入確定ボタン
            driver.find_element_by_id('order-button').click() 
        
        driver.close()
        break

How to use

↑から自分のChromeのバージョンに合ったChrome driverをダウンロード後,スクリプトと同ディレクトリ内に設置

# config for login
EMAIL = "taro.rakuten@rakuten.com"
PASSWORD = "mypassword"

を自分のYogiboアカウントへ置き換える

コマンドライン上で下記コマンド実行

$ python3 yogibo.py

※決済方法として銀行振り込みを指定している.
クレジットカードで支払う場合は

# config for credit card
CARDNUMBER = "0000111122223333"
FIRSTNAME = "TARO"
LASTNAME = "RAKUTEN"
EXPIREDMONTH = "03"
EXPIREDYEAR = "23"
SECURITYCODE = "999"

を自身のクレジットカード情報へ修正し,フォーム入力を実行するため以下のようにアクティベート状態にする

# クレジットカード情報の入力
driver.find_element_by_id('gmo_payment_card_no').send_keys(CARDNUMBER)
driver.find_element_by_id('gmo_payment_method').send_keys('一括払い')
driver.find_element_by_id('gmo_payment_security_code').send_keys(SECURITYCODE)
driver.find_element_by_id('gmo_payment_expire_month').send_keys(EXPIREDMONTH)
driver.find_element_by_id('gmo_payment_expire_year').send_keys(EXPIREDYEAR)
driver.find_element_by_id('gmo_payment_card_name1').send_keys(FIRSTNAME)
driver.find_element_by_id('gmo_payment_card_name2').send_keys(LASTNAME)

またテスト時は

# 購入確定ボタン(※購入してしまうのでテスト時はコメントアウトしておく!!!)
driver.find_element_by_id('order-button').click() 

# 購入確定ボタン(※購入してしまうのでテスト時コメントアウトしておく!!!)
# driver.find_element_by_id('order-button').click() 

の状態にしておく(でないと予定にない購入をしてしまう)

Evaluation

試しに下記商品を自動購入することで本ツールの事前評価を行なった

サイズ選択 カラー選択 販売開始時刻(仮) スクリプト実行時刻
L Blue 2022年11月23日 19:00 2022年11月23日 18:30
評価項目 速度[s]
スクリプト実行→ログインPL完了 2.23
ログインPL完了→認証完了 0.34
販売開始時刻→購入完了 1.67

Conclusion

販売開始時刻→購入完了2.0秒以下という結果から,速度的にはセール開始時刻とほぼ同時に購入完了可能と結論づけることができる.ただし,懸念していることが2点ある.それは,セール開始と同時に,現在https://yogibo.jp/midnight2022 でマッピングされている各対象商品ページURLがセール用に変更されてしまわないかと言う点.もし変更されてしまうと,それに対してスクリプトが適用できなくなる...😭.もう一つはロードバランサー等インフラ側でそもそもリクエストが弾かれてしまうまたは503などのタイムアウトがありうる点である.

まあ準備は完璧!あとは25日を待つのみ

以上

Ref

追記

日付:2022/11/27
結果:購入できませんでした(しませんでした)
理由:狙ってたYogiboがまさかの10%オフ(小計:17,622円)により

# きちんと半額になってるのを確認してから購入確定ボタンをプッシュ
if  driver.find_element_by_class_name('item-sum').text == "小計:8,900円":
    # 購入確定ボタン
    driver.find_element_by_id('order-button').click()

の購入確定ボタンクリックの行が実行されずにそこでボットが処理停止したから

まあ10%なら元々買う気なかったらいいか.

久しぶりにPythonかくきっかけにはなりました.おしまい.

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?