LoginSignup
2
2

More than 3 years have passed since last update.

PythonのSeleniumでnanacoギフトコードを自動登録

Last updated at Posted at 2020-05-14

追記 2020/6/6

nanacoギフトコードを直接指定できるように変更しました。
登録失敗時に再登録を試みるよう変更しました。

追記 2020/5/15

nanaco番号などがスクリプトに入力されていない場合、実行時に尋ねるように変更しました。
合わせて本記事に書かれている手順も見直しました。

概要

PythonでSeleniumを使用し、nanacoギフトコードの取得から登録までを自動化します。
nanacoギフトコードの取得をせずに、予めストックしておいたギフトコードの登録も可能です。
入力支援ではなく、自動化です。
※福利厚生倶楽部のギフトコードでテストしました。その他の場所で購入したギフトコードはテストしていませんのでご注意ください。
※下記ツイート内の動画は早送りしておらず等倍再生です。また、コンソール画面には全てMISSEDと表示されていますが、2回目の実行のため重複登録扱いになっているためです。実際に1回目の実行時は正しく登録されてOKと表示されますのでご安心ください。

スクリプト実行までの準備(初回限定)

  1. 最新のPython3をインストールします。すでにインストールされている場合は次の手順に進んでください。
    上記サイトよりインストールする場合、「パスに追加する」旨のチェックボックスをオンにしてください。

    ※画像はhttps://www.javadrive.jp/python/install/index3.html より引用

  2. 最新のChromeをインストールします。すでにインストール済みの場合は次の手順に進んでください。

  3. 追加ライブラリをインストールします。Windowsならコマンドプロンプト、Macならターミナルで下記コマンドを実行してください。
    ※環境に応じてpipまたはpip3で実行してください。

    pip3 install selenium
    pip3 install chromedriver-binary
    
  4. 下記スクリプトをコピーし、メモ帳などのテキストエディタに貼り付け、nanaco_transiter.pyというファイル名で保存してください。
    この時、福利厚生倶楽部のIDやnanaco番号などをスクリプト内に記載すると、実行がスムースになります。記載する欄は8行目から10行目です。

nanaco_transiter.py
#!/usr/bin/env python3
import time
import re
from sys import argv
import selenium
from selenium import webdriver

userName = "" # <- 購入した福利厚生倶楽部のIDを6桁と4桁で入力してください(例: 012345-6789)
nanacoNo = "" # <- nanaco番号16桁を入力してください(例: 0123456789012345)
securityCode = "" # <- カード記載の番号を7桁で入力してください(例: 0123456)

def getGiftCodes(driver, url):
    driver.get(url.strip())
    driver.find_element_by_name("kainno").send_keys(userName)
    driver.find_element_by_class_name("next").click()
    elements = driver.find_elements_by_css_selector(".table_gift tbody tr")
    giftCodes = []
    for element in elements:
        texts = element.text.split(" ")
        if re.match("^[a-zA-Z\d]{16}$", texts[-3]):
            giftCodes.append(texts[-3])
    return giftCodes

# nanacoサイトのセッションを張る
def loginNanaco(driver):
    driver.get('https://www.nanaco-net.jp/pc/emServlet')
    driver.find_element_by_name("XCID").send_keys(nanacoNo)
    driver.find_element_by_name("SECURITY_CD").send_keys(securityCode)
    driver.find_element_by_name("ACT_ACBS_do_LOGIN2").click() # ここでログイン
    time.sleep(1)
    driver.find_element_by_link_text("nanacoギフト登録").click()
    time.sleep(1)

# セッション内でギフトコードを登録する
def registGiftCode(driver, code, continueCount = 0):
    driver.find_element_by_xpath("//input[@alt=\"ご利用約款に同意の上、登録\"]").click() # ここで新規ウィンドウが開く
    time.sleep(1)
    driver.switch_to.window(driver.window_handles[1]) # 直前に開いた新規ウィンドウをカレントにする

    try:
        driver.find_element_by_id("gift01").send_keys(code[:4])
        driver.find_element_by_id("gift02").send_keys(code[4:8])
        driver.find_element_by_id("gift03").send_keys(code[8:12])
        driver.find_element_by_id("gift04").send_keys(code[12:])

        driver.find_element_by_id("submit-button").click()
        time.sleep(0.1)
        result = "Succeeded"
        driver.find_element_by_xpath("//input[@alt=\"登録する\"]").click()
    except selenium.common.exceptions.NoSuchElementException:
        result = "Duplicated" if "このギフトIDは、すでに下記の通り登録済です。" in driver.page_source else "Missed"
    time.sleep(0.1)
    driver.close() # カレントウィンドウ(さっき開いた新規ウィンドウ)を閉じる
    driver.switch_to.window(driver.window_handles[0]) # nanacoページのウィンドウをカレントにする
    return result if result != "Missed" or continueCount >= 5 else registGiftCode(driver, code, continueCount + 1)

# 入力内容を整理して正しくスクリプトが動作するようにする
# 必要変数が空の場合、対話形式で補完していく
def checkEnviroment(arg):
    global userName, nanacoNo, securityCode
    if not userName:
        print("購入した福利厚生倶楽部のIDを6桁と4桁で入力してください(例: 012345-6789)")
        userName = input()
    if not nanacoNo:
        print("nanaco番号16桁を入力してください(例: 0123456789012345)")
        nanacoNo = input()
    if not securityCode:
        print("カード記載の番号を7桁で入力してください(例: 0123456)")
        securityCode = input()
    urlsOrGiftCodes = []
    if len(arg) < 2:
        print("nanacoギフトコード、またはnanacoギフトコードを表示するためのURLを1行ずつ入力してください。")
        print("全て入力し終わったら、何も入力せずにEnterを押してください。")
        while True:
            code = input()
            if urlsOrGiftCodes and not bool(code):
                break
            if code.strip() != "":
                urlsOrGiftCodes.append(code.strip())
    else:
        for code in arg[1:]:
            urlsOrGiftCodes.append(code.strip())
    return urlsOrGiftCodes

if __name__ == "__main__":
    urlsOrGiftCodes = checkEnviroment(argv)
    print("Preparing...")
    driver = selenium.webdriver.Chrome()
    driver.set_page_load_timeout(30)
    print("Getting gift codes ...")
    giftCodes = []
    for code in urlsOrGiftCodes:
        # 入力内容がURLの場合、コードを取得しにいく
        if code[:8] == "https://":
            giftCodes += getGiftCodes(driver, code)
        # 入力内容がURLでない場合、それがギフトコードとして扱う
        else:
            giftCodes.append(code)
    print("Logging in nanaco website ...")
    loginNanaco(driver)

    progress = {}
    print("Registing codes ...")
    for giftCode in giftCodes:
        print(giftCode, "...", end = "\r")
        result = registGiftCode(driver, giftCode)
        if not result in progress:
            progress[result] = 0
        progress[result] += 1
        print(giftCode, "(%d/%d)" % (sum(progress.values()), len(giftCodes)), result)

    for key in progress:
        print(key + ":", progress[key])
    print("Total:", sum(progress.values()))
    driver.find_element_by_id("memberInfoInner").click()
    driver.quit()

Githubにも掲載しています。

実行方法

Windowsならコマンドプロンプト、Macならターミナルで下記コマンドを実行してください。
※環境に応じてpythonまたはpython3で実行してください。

python3 nanaco_transiter.py "ギフトコードのURL"|"ギフトコード" ["ギフトコードのURL"|"ギフトコード" ...]

実行例

python3 nanaco_transiter.py "https://www.fukuri.net/main/www/gift/login.jsp?jujuno=xxxxxxxxxx&cococd=xx" da1Ddf2fffsd4589 fffsd4589da1Ddf2 "https://www.fukuri.net/main/www/gift/login.jsp?jujuno=yyyyyyyyyy&cococd=yy"

上記の場合、URL指定した2つのページよりnanacoギフトコードを取得し、ギフトコード指定した2つのギフトコードと合わせて登録を行います。

出力結果

スクリプトの進捗状況と、各ギフトコードの登録結果を表示します。
各ギフトコードの出力結果「ギフトコード 進捗度合い 登録結果」で表示されます。
表示例は次のとおりです。

abcdefgHIJ123456 (13/20) Succeeded

登録結果は以下の3種類で表示されます。

登録結果 説明
Succeeded 登録に成功しました
Duplicated すでに登録されています
Missed 5回試行しましたが、5回とも登録に失敗しました。正しいギフトコードかどうかとネットワーク環境を確認してください

その他

  • 引数に何も入力せずに実行した場合、実行時に入力を求められます。ギフトコードが記載されてるURLか、ギフトコードを1行ずつ入力してください。
  • 引数のURLは""で括る必要があります。括らない場合、文字列中の&をシェル命令の&と解釈されてしまい正しく動作しません。ギフトコードの場合は括らなくても問題ありません。
  • 引数の場合も実行中に入力の場合も、ギフトコードとURLは混在して入力できます。
  • ギフトコードの登録に失敗した場合、成功するまで最大5回繰り返します。全て失敗した場合、Missedと表示されます。
  • 福利厚生倶楽部のIDの入力は必須です。全てギフトコードを入力した場合はテキトーな値を入力してください。
  • 細かなエラー処理は実装していません。本来の使い方でご使用ください。
  • ギフトコードの登録中に落ちてしまっても、再実行すれば問題なく登録できます。
  • 不具合などありましたらご連絡いただけると助かります。

免責

  • このスクリプトの実行は全て自己責任でお願いします。
  • このスクリプトに悪意ある動作は含めていませんが、万一不具合によって実行者が被害を被ったとしても、作者は一切の責任を負いませんのでご注意ください。
2
2
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
2
2