まいにち右往左往

日記です。興味の範囲がバラバラで統一性がない日記です。だんだん備忘録っぽくなってきました。

Splatoon2 の戦績をPythonでGoogle Spread Sheetに保存する

だいぶ回り道をしたせいで、時間がけっこうかかりました。こんなことをやっている時間でゲームをしたほうがウデマエも上がるんじゃないかって気がします。

それはそれとして、Googleスプレッドシートスプラトゥーン2の戦績を記録しはじめました。

長くて見づらくなってしまいましたので、改行しているときは\で明示的にしめしてあります。

 

コードの中の'GoogleAPI認証用json'は、GoogleスプレッドシートAPIを有効化した時に作成した認証情報が含まれたjsonファイルです。Pythonのファイルと同じ場所に置いてあります。

'スプレッドシートID'は事前に作成したスプレッドシートのURLに表示されたd/の後から/までの文字列です。

iksm_sessionの値はプロキシなり、端末内に保存されたcookieなり、から読み取った値です。

  

# -*- coding: utf-8 -*-

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 #spreadSheetバトルナンバー最大値取得 def maxBattleNumber(): scope = ['https://spreadsheets.google.com/feeds',\ 'https://www.googleapis.com/auth/drive'] #Pythonファイルと同じ場所に置いたGoogleAPI接続認証用のjsonからキーを取り出し 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 # URL(Splatoon API)にアクセス、JSONデータをreturn 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): # 記録済みのbattle_numberを除外するためスプレッドシートのbattle_numberの最大値を取得 maxValues = maxBattleNumber() for result in jsonData["results"]: #詳細の戦績取得用のURLを作成 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'] #以降、欲しい要素をすべて変数に入れる #SpreadSheetに入れる要素を配列にまとめる battleresult = [[battle_number,elapsed_time,\
estimate_gachi_power, my_team_count,\
my_team_result_name, other_team_count]] #spreadsheetへの書き込み 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の戦績は、シートに記載されていない新しい戦績ということになるのです。次の関数の部分ですね。 

#spreadSheetバトルナンバー最大値取得
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"]

からさらに詳細の戦績を取得します。
詳細の戦績を取得後は、記録したい要素をいったん変数にいれてから配列にまとめ、スプレッドシートに書き込みます。一件ずつ書き込まないのはGoogleAPIの制限が100秒間に100件までとなっているからですね。

 

バトル一回分のデータを書き込んだら、次のバトルのデータを取得するまで5秒の待機をさせています。もともと公開されていないAPIを叩いているので、できるだけ負荷はかけないような形にしたかったのです。どうせ自動的にデータを集めるので、そこにきて多少の待ち時間が発生しても、運用上は問題ないですし。

 

反省点として、スプレッドシートへの書き込みは、それだけで一つの関数にまとめたほうがわかりやすかった気がします。まあでも動いているのでとりあえずはいいか。

 

これでしばらくはゲームに専念してデータをためることにします!

遊べるぞー!