Splatoon2のAPIをPythonで叩いて戦績を取得・保存する


何の記事なの?

  • イカリング2が使ってる戦績取得APIをPythonから叩き、Jsonファイルに保存する
  • 定期実行タスクとして設定し、定期的に戦績を取得させる

導入

みなさん、こんにちは。イカやってますか?イカ。

自分は発売日にマリオオデッセイを買ったものの一度も起動せずにイカやりまくってます。バカかな?

さて、もう3週間も前のことですが、前回の記事ではイカリング2が使ってるAPIを確認し、
iksm_sessionキーなるものを使って、イカリング2を使わずに戦績やガチマッチの情報を取得しました。

前回記事:Splatoon2のAPIを叩いてみる

最終的には、戦績を適宜取得しDBで管理、データの統計を取ったりとかしてみたいですね。

でも、DB用意してJson流し込んだりする気力が今はないので、今回はDBで管理する前段階として、
一先ず戦績をJsonファイルで保存しておきたいと思います。

戦績は過去50戦分しか遡れませんから、とりあえずこれだけでもやっておかないと貴重な(?)データが減っちゃいます。

早速コードを書く

Pythonを普段使ってないので調べながらせこせこ書きました。。

また、同じようにPythonを使ってAPIを叩いていらっしゃる先駆者様がいらっしゃったので、かなり参考にさせていただきました。
ありがとうございました
[Python]イカリング2のJsonを取得してみた

早速コードを貼っちゃいます。

SplatoonAPIKnocker.py
import urllib
from urllib.request import build_opener, HTTPCookieProcessor
from urllib.parse import urlencode
import http
from http.cookiejar import CookieJar
import json
import os

# 引数のURL(Splatoon API)にアクセス、レスポンスのJSONデータをreturn
def getJson(url): # UrlにアクセスしJsonを取得
    cookie = "iksm_session=自分のiksm_sessionキー"
    opener = build_opener(HTTPCookieProcessor(CookieJar()))
    opener.addheaders.append(("Cookie", cookie))
    res = opener.open(url)
    return json.load(res)

# 引数のJSONデータ(戦績データを期待)を戦績ごとにファイルに保存
def saveButtleResults(jsonData):
    for result in jsonData["results"]:
        # この戦績に対応するファイル名とパスを組み立てる
        outputFilePath = "保存先のパス/result-buttle-" + result["battle_number"] + ".json"
        # この戦績ファイルが既に存在するか確認、なかったら作成・書き込み
        if not(os.path.exists(outputFilePath)) :
            outputFile = codecs.open(outputFilePath, "w", encoding="utf-8")
            json.dump(result, outputFile, ensure_ascii=False, indent=4, sort_keys=True)
            outputFile.close()

saveButtleResults(getJson("https://app.splatoon2.nintendo.net/api/results"))

簡単に説明しますと、
 ・先駆者様のコードを参考に、URLにクッキー付きでアクセス、Jsonデータを取得
 ・取得したJsonデータのresults要素の中にある各戦績を、「result-buttle-[対戦No.].json」というファイル名で、ファイルが存在しなかったら保存
以上の単純な内容です。入力値チェックとかも入れてません。
(こういう処理を書くときのあるある「文字化け」に若干悩まされました…)

iksm_sessionキーファイルの保存先のパスを書き換えてもらうとそのまま実行できるはずです。

これを実行すると、指定のパスにイカの画像のようにファイルが保存されます。

各ファイルの中身はこんな感じです。

戦績データがきれいに書き込めてます。よかったよかった

定期的に実行されるようにする

Windowsなので標準機能の「タスクスケジューラ」を使って定期的に実行されるタスクを設定します。

参考:http://desktop.arcgis.com/ja/arcmap/10.3/analyze/executing-tools/scheduling-a-python-script-to-run-at-prescribed-times.htm
参考:https://tonari-it.com/windows-task-schdeuler/

タスクスケジューラを開いたら、基本タスクの作成から画面表示に沿って進んでいけば作成できます。

Windows以外のOSの方は cron で調べると色々出てきますので、それを参考にしてください。

問題として、iksm_sessionキーは一定期間(詳細未確認)で値が変更されるので、値が変わったらまた取得しなおさないといけません。
いずれは、コードの先頭で、自分のニンテンドーアカウントで認証して動的にiksm_sessionキーを取得するようにできたらいいですね。

(追記)
iksm_sessionキーの自動取得のためにごにょごにょとNintendo Switch Onlineの通信内容見たりしたんですが、肝心のiksm_sessionキー取得の部分だけうまくいってません。
体感3~4日で値が切り替わるのですが、現状、そのつど通信見て手動で更新するしかなさそうです。まぁそんなもんですよね。。

終わりに

今回は短いですが以上です。

残りタスクですが、
・iksm_sessionキーを動的に取得する
・集めたJsonデータをDBに移す
・URLから取得したJsonデータを直接DBに流し込む
くらいですかね。

また、これとは別にガチマッチのスケジュールとかゲソタウンの商品情報を通知してくれるアプリとか自分で作ってみたいです。
こっちの方を先にやるかもしれません

それでは皆様、良いイカライフを。

参考文献

https://qiita.com/gahaq/items/d8d06c111e2518bfbc87
http://desktop.arcgis.com/ja/arcmap/10.3/analyze/executing-tools/scheduling-a-python-script-to-run-at-prescribed-times.htm