だいぶ回り道をしたせいで、時間がけっこうかかりました。こんなことをやっている時間でゲームをしたほうがウデマエも上がるんじゃないかって気がします。
それはそれとして、Googleスプレッドシートにスプラトゥーン2の戦績を記録しはじめました。
長くて見づらくなってしまいましたので、改行しているときは\で明示的にしめしてあります。
コードの中の'GoogleAPI認証用json'は、GoogleのスプレッドシートAPIを有効化した時に作成した認証情報が含まれたjsonファイルです。Pythonのファイルと同じ場所に置いてあります。
'スプレッドシートID'は事前に作成したスプレッドシートのURLに表示されたd/の後から/までの文字列です。
iksm_sessionの値はプロキシなり、端末内に保存されたcookieなり、から読み取った値です。
from urllib.request import build_opener, HTTPCookieProcessor
from http.cookiejar import CookieJar
import json
from oauth2client.service_account import ServiceAccountCredentials
import httplib2
from apiclient import discovery
from time import sleep
def maxBattleNumber():
scope = ['https://spreadsheets.google.com/feeds',\
'https://www.googleapis.com/auth/drive']
credentials = ServiceAccountCredentials.\
from_json_keyfile_name('GoogleAPI認証用json', scope)
http = credentials.authorize(httplib2.Http())
discoveryUrl = ('https://sheets.\
googleapis.com/$discovery/rest?version=v4')
service = discovery.build('sheets', 'v4', http=http,\
discoveryServiceUrl=discoveryUrl)
spreadsheetId = 'スプレッドシートID'
rangeName = 'A2:A'
result = service.spreadsheets().values().get(\
spreadsheetId=spreadsheetId, range=rangeName).execute()
values = result.get('values', [])
maxValue=max(values)[0]
maxValue=int(maxValue)
return maxValue
def getJson(url):
cookie = "iksm_session=iksm_sessionの値"
opener = build_opener(HTTPCookieProcessor(CookieJar()))
opener.addheaders.append(("Cookie", cookie))
res = opener.open(url)
return json.load(res)
def getButtleResults(jsonData):
maxValues = maxBattleNumber()
for result in jsonData["results"]:
url = "https://app.splatoon2.nintendo.net/api/results/"\
+ result["battle_number"]
resultBattleNumber = result["battle_number"]
resultBattleNumber = int(resultBattleNumber)
if resultBattleNumber > maxValues:
battleResult = getJson(url)
battle_number = battleResult['battle_number']
elapsed_time = battleResult['elapsed_time']
estimate_gachi_power = battleResult['estimate_gachi_power']
my_team_count = battleResult['my_team_count']
my_team_result_name = battleResult['my_team_result']['name']
other_team_count = battleResult['other_team_count']
battleresult = [[battle_number,elapsed_time,\
estimate_gachi_power, my_team_count,\
my_team_result_name, other_team_count]]
scope = ['https://spreadsheets.google.com/feeds',\
'https://www.googleapis.com/auth/drive']
credentials = ServiceAccountCredentials.\
from_json_keyfile_name('GoogleAPI認証用json', scope)
http = credentials.authorize(httplib2.Http())
discoveryUrl = ('https://sheets.\
googleapis.com/$discovery/rest?version=v4')
service = discovery.build('sheets', 'v4', http=http,\
discoveryServiceUrl=discoveryUrl)
spreadsheetId='スプレッドシートID'
rangeName = 'A:DA'
ValueInputOption = 'USER_ENTERED'
body = {
'values': battleresult,
}
service.spreadsheets().values().append(\
spreadsheetId=spreadsheetId, range=rangeName,\
valueInputOption=ValueInputOption, body=body).execute()
sleep(5)
getButtleResults(getJson("https://app.splatoon2.nintendo.net/api/results"))
まずは、事前に作成したスプレッドシートのbattle_Numberの列(今回はA列に記録してあります)の最大値を取得します。この最大値より大きいbattle_Numberの戦績は、シートに記載されていない新しい戦績ということになるのです。次の関数の部分ですね。
def maxBattleNumber():
次に戦績の概要を取得します。
def getJson(URL):
"https://app.splatoon2.nintendo.net/api/results"からは、戦績の概要がjsonとして取得できます。jsonの中は、一戦ごとにbattle_numberが振られたresultsに分かれています。まずはそのbattle_numberから新しい記録かどうかを判別したいので、取得したjsonを引数に、次の関数に移ります
def getButtleResults(jsonData):
この中で、maxBattleNumber()で取得した、スプレッドシートに記録されたbattle_numberの最大値と比較しています。その結果、まだスプレッドシートに記載されていない戦績であれば、
"https://app.splatoon2.nintendo.net/api/results/" + result["battle_number"]
からさらに詳細の戦績を取得します。
詳細の戦績を取得後は、記録したい要素をいったん変数にいれてから配列にまとめ、スプレッドシートに書き込みます。一件ずつ書き込まないのはGoogleのAPIの制限が100秒間に100件までとなっているからですね。
バトル一回分のデータを書き込んだら、次のバトルのデータを取得するまで5秒の待機をさせています。もともと公開されていないAPIを叩いているので、できるだけ負荷はかけないような形にしたかったのです。どうせ自動的にデータを集めるので、そこにきて多少の待ち時間が発生しても、運用上は問題ないですし。
反省点として、スプレッドシートへの書き込みは、それだけで一つの関数にまとめたほうがわかりやすかった気がします。まあでも動いているのでとりあえずはいいか。
これでしばらくはゲームに専念してデータをためることにします!
遊べるぞー!