#はじめに
前回、こちらの記事で、dアニメストアのランキングを自動取得する方法を紹介しました。
ですが、前回の方法はお世辞にもいいやり方とは言えません。
なぜなら、Googleスプレッドシートの他にもHerokuやSpreadsheet APIを使っていたりと管理が大変だからです。
今回は、Googleスプレッドシート(とGAS)で完結させる方法をご紹介します。
#完成像
今回はランキングに加えてマイリスト登録数とお気に入り登録数も取得します。
#データのソース
前回に引き続き、JSONファイルを取得します。詳しいデータ構造についてはこの部分をご覧ください。
前回は作品のタイトル名workTitle
しか取得しませんでしたが、今回はマイリスト登録数myListCount
とお気に入り登録数favoriteCount
も取ってきます。
{
"workId": "25182",
"workInfo": {
"workTitle": "ありふれた職業で世界最強 2nd season",
"link": "https://anime.dmkt-sp.jp/animestore/ci_pc?workId=25182",
"mainKeyVisualPath": "https://cs1.anime.dmkt-sp.jp/anime_kv/img/25/18/2/25182_1_1.png?1638419407000",
"mainKeyVisualAlt": "ありふれた職業で世界最強 2nd season_1",
"scenes": [
{
"(省略)"
}
],
"workIcons": [],
"myListCount": 36310,
"favoriteCount": 109694,
"workTypeList": [
"anime"
],
"vodType": "svod",
"ageLimitType": "0",
"workIconInfoList": [
"(省略)"
]
},
"rankingInfo": {
"rank": 1,
"arrowIcon": "rankUp"
}
},
例えばこの場合、作品名(workTitle
)「ありふれた職業で世界最強 2nd season」は、 rankingInfo
のrank
から順位が1位ということがわかります。
さらに、マイリスト登録数(myListCount
)は36310、お気に入り登録数(favoriteCount
)は109694ということまで読み取れます。
あとは、これをスプレッドシートに落とし込むだけです。
#方法
前回の記事では、PythonでJSONファイルを取得しSpreadsheet APIでスプレッドシートに書き込む仕様でしたが、今回はGASでJSONを取り直接スプレッドシートに書き込みます。
使うのは、 GASのUrlFetchAppクラスのfetchメソッド。
簡単に説明すると、JSONを取ってきて文字列で返してくれます。
let response = UrlFetchApp.fetch("https://anime.dmkt-sp.jp/animestore/rest/WS000103?rankingType=01").getContentText();
// console.log(response)で確認すると↓(見にくいので適宜改行しています)
//Logging output too large. Truncating output.
//{"resultCd":"00","version":"1.5","selfLink":"https://anime.dmkt-sp.jp/animestore/rest/WS000103?rankingType=01",
//"data":{"maxCount":4520,"count":300,"workList":[{"workId":"25182","workInfo":
//{"workTitle":"ありふれた職業で世界最強 2nd season","link":
//"https://anime.dmkt-sp.jp/animestore/ci_pc?workId=25182",
//"mainKeyVisualPath":"https://cs1.anime.dmkt-sp.jp/anime_kv/img/25/18/2/25182_1_6.png?1638419407000","mainKeyVisualAlt":
//"ありふれた職業で世界最強 2nd season_6","workIcons":[],"myListCount":36839,"favoriteCount":110594,"workTypeList":
//["anime"],"vodType":"svod","ageLimitType":"0","workIconInfoList":
//["1","1","0","0","0","1","0","0","0","0","0","0","0","0","1","0","0","0","1"]},"rankingInfo":
//{"rank":1,"arrowIcon":"rankStay"}},{"workId":"25202","workInfo":{"workTitle":"その着せ替え人形は恋をする",
//"link":"https://anime.dmkt-sp.jp/animestore/ci_pc?workId=25202",
//"mainKeyVisualPath":"https://cs1.anime.dmkt-sp.jp/anime_kv/img/25/20/2/25202_1_6.png?1639560672000",
//"mainKeyVisualAlt":"その着せ替え人形は恋をする_6","workIcons":[],"myListCount":50013,"favoriteCount":133348,"workTypeList":["anime"],"vodType":"svod","ageLimitType":"0","workIconInfoList":["1","1","0","0","0",
// (以下省略)
// データ量が多くて一部しか表示できていませんが、データ自体はきちんと取れていますね。
ですが、文字列で返されても扱いにくいです。
そのため、二度手間感はありますが、文字列を扱いやすいJSONに変換します。
let jsonData = JSON.parse(response);
// console.log(jsonData)で確認すると↓
//{ resultCd: '00',
// version: '1.5',
// selfLink: 'https://anime.dmkt-sp.jp/animestore/rest/WS000103?rankingType=01',
// data:
// { maxCount: 4520,
// count: 300,
// workList:
// [ [Object],
// [Object],
// [Object],
// [Object],
// (省略)
//この段階では、各作品のデータは[Object]内に格納されたままなので、次の手順で取り出す必要があります。
これで変数jsonData
にランキングのJSONを格納できました。
dアニメストアのランキングJSONはかなり複雑です。
前回説明した通り、作品それぞれのデータはdata
という階層の中のworkList
という階層に入っています。
(ややこしいですが、上下関係としては data
> workList
> 作品データ
という感じです。)
JavaScriptでJSONを扱うとき、奥の階層へアクセスするにはドットでつなげます。
let list = jsonData.data.workList
// console.log(list)で確認すると↓
//Logging output too large. Truncating output. [ { workId: '25182',
// workInfo:
// { workTitle: 'ありふれた職業で世界最強 2nd season',
// link: 'https://anime.dmkt-sp.jp/animestore/ci_pc?workId=25182',
// mainKeyVisualPath: 'https://cs1.anime.dmkt-sp.jp/anime_kv/img/25/18/2/25182_1_6.png?1638419407000',
// mainKeyVisualAlt: 'ありふれた職業で世界最強 2nd season_6',
// workIcons: [],
// myListCount: 36846,
// favoriteCount: 110599,
// workTypeList: [Object],
// vodType: 'svod',
// ageLimitType: '0',
// workIconInfoList: [Object] },
// rankingInfo: { rank: 1, arrowIcon: 'rankStay' } },
// { workId: '25202',
// workInfo:
// { workTitle: 'その着せ替え人形は恋をする',
// link: 'https://anime.dmkt-sp.jp/animestore/ci_pc?workId=25202',
// mainKeyVisualPath: 'https://cs1.anime.dmkt-sp.jp/anime_kv/img/25/20/2/25202_1_6.png?1639560672000',
// mainKeyVisualAlt: 'その着せ替え人形は恋をする_6',
// workIcons: [],
// myListCount: 50029,
// favoriteCount: 133362,
// workTypeList: [Object],
// (以下省略)
// データ量が多くて一部しか表示できていませんが、データ自体はきちんと取れていますね。
この場合、jsonData
の中にあるdata
の中にあるworkList
を変数list
に格納しています。
では、次に配列を用意して作品データを書き込んでいきましょう。
let outputList = [] //配列を用意
let listLength = list.length //for文を回す回数を、先ほどのJSON``list``の長さ(データ個数)から取得
for (let i = 0; i < listLength; i++) { //カウントは0から始まります。
let rank = list[i].rankingInfo.rank //listの中のi個目のランク順位
let title = list[i].workInfo.workTitle //listの中のi個目の作品タイトル
let myList = list[i].workInfo.myListCount //listの中のi個目の作品のマイリスト登録数
let favorite = list[i].workInfo.favoriteCount //listの中のi個目の作品のお気に入り登録数
outputList.push([rank, title, myList, favorite]) //配列に挿入
}
// 全ての作品を配列に挿入し終わった後でconsole.log(outputList)で確認すると↓
//Logging output too large. Truncating output. [ [ 1, 'ありふれた職業で世界最強 2nd season', 36854, 110610 ],
// [ 2, 'その着せ替え人形は恋をする', 50045, 133397 ],
// [ 3, 'からかい上手の高木さん3', 19666, 55448 ],
// [ 4, '天才王子の赤字国家再生術', 27624, 74302 ],
// [ 5, '失格紋の最強賢者', 35218, 99288 ],
// [ 6, '終末のハーレム', 17993, 47997 ],
// (以下省略)
// データ量が多くて一部しか表示できていませんが、データ自体はきちんと取れていますね。
このままでは配列の中のそれぞれの数字が何を指すかわかりませんので、↑のコードのlet outputList = []
の部分を以下のように置き換えます。
let outputList = [['順位', '作品名', 'マイリスト', 'お気に入り']]
さらに、ランキングの取得時間といつのデータか日時を加えます。
let date = new Date();
let today = Utilities.formatDate(date, 'JST', 'yyyy-MM-dd kk:mm:ss') //今日の時間
date.setDate(date.getDate() - 1) //変数dateを一日戻し、
let yesterday = Utilities.formatDate(date, 'JST', 'yyyy-MM-dd') //昨日の日時として定義
配列の中に取得日時を加えたいため、let outputList = [['順位', '作品名', 'マイリスト', 'お気に入り']]
の部分に日時を加えます。(dアニメストアのランキングは、昼12時に前日分のランキングを表示)
let outputList = [[yesterday, '(' + today + '取得)', '', ''], ['順位', '作品名', 'マイリスト', 'お気に入り']]
よって、ここまでのコードを合わせると以下のようになります。
function danimeDaily() {
let response = UrlFetchApp.fetch("https://anime.dmkt-sp.jp/animestore/rest/WS000103?rankingType=01").getContentText();
let jsonData = JSON.parse(response);
let list = jsonData.data.workList
let date = new Date();
let today = Utilities.formatDate(date, 'JST', 'yyyy-MM-dd kk:mm:ss')
date.setDate(date.getDate() - 1);
let yesterday = Utilities.formatDate(date, 'JST', 'yyyy-MM-dd')
let outputList = [[yesterday, '(' + today + '取得)', '', ''], ['順位', '作品名', 'マイリスト', 'お気に入り']]
let listLength = list.length
for (let i = 0; i < listLength; i++) {
let rank = list[i].rankingInfo.rank
let title = list[i].workInfo.workTitle
let myList = list[i].workInfo.myListCount
let favorite = list[i].workInfo.favoriteCount
outputList.push([rank, title, myList, favorite])
}
}
あとは、この配列をスプレッドシートに書き込むだけ。
まずは、スプレッドシートを取得(以下、スプレッドシートIDとシート名を自身のものに書き換えてください。)。
const daily = SpreadsheetApp.openById("スプレッドシートID").getSheetByName('シート名')
毎日取得してどんどん右にデータを追記していきたいので、最終列を取りその横に配列のデータを貼り付けます。
let lastCol = daily.getLastColumn() //最終列を取得
daily.getRange(1, lastCol + 1, 302, 4).setValues(outputList) //最終列の右の列1行目に、縦302(データ数(300)+日時+目次)、横4(順位+作品名+マイリスト登録数+お気に入り登録数)の配列を貼り付け
最終的にコードの全容は以下のようになります。
const daily = SpreadsheetApp.openById("スプレッドシートID").getSheetByName('シート名')
function danimeDaily() {
let response = UrlFetchApp.fetch("https://anime.dmkt-sp.jp/animestore/rest/WS000103?rankingType=01").getContentText();
let jsonData = JSON.parse(response);
let list = jsonData.data.workList
let date = new Date();
let today = Utilities.formatDate(date, 'JST', 'yyyy-MM-dd kk:mm:ss')
date.setDate(date.getDate() - 1);
let yesterday = Utilities.formatDate(date, 'JST', 'yyyy-MM-dd')
let outputList = [[yesterday, '(' + today + '取得)', '', ''], ['順位', '作品名', 'マイリスト', 'お気に入り']]
let listLength = list.length
for (let i = 0; i < listLength; i++) { //
let rank = list[i].rankingInfo.rank
let title = list[i].workInfo.workTitle
let myList = list[i].workInfo.myListCount
let favorite = list[i].workInfo.favoriteCount
outputList.push([rank, title, myList, favorite])
}
let lastCol = daily.getLastColumn()
daily.getRange(1, lastCol + 1, 302, 4).setValues(outputList)
}
以上のコードを実行すると、次のようなアウトプットになります。
あとは、関数danimeDaily
を毎日13時以降に実行させるようトリガーをセットします。
(dアニメストアは前日のランキングを当日昼12時に更新するため)
トリガーをセットすることで、毎日実行されてどんどんデータが追加されていくわけです。
今回は以上になります!