Switch是我目前的主力游戏平台,在实现了Steam游戏数据采集以后,一直有实现Switch数据采集的执念。相较于可以使用Steam官方的API接口,任天堂官方并没有向普通用户开放接口,使得Switch游戏数据的获取极为困难。但因为Jump等一些应用平台上都上线了Switch账户绑定与游戏时长统计的功能,使我相信一定是有办法可以实现Switch数据采集的。
起初想在任天堂官网找到相关的开发文档,但是并没有收获,反倒是发现目前网上的一些可行方案都是社区通过逆向工程解析出的Web API,不过流程相当复杂。好在最终找到了一篇基于python实现的文章,得以将流程跑通。
因为我都是使用日服账号进行游戏,并开通了任天堂会员以同步游戏数据到云服务器,所以我的所有游玩记录都集中在日服账号上。本文计划获取自己Switch日服账户中所有游戏的信息以及各时段的游玩时长记录,并存储到个人数据中心当中。
封装接口
Switch接口调用的流程如下:
由于接口调用流程步骤较多且复杂,我将其封装为三个函数方便后期使用:
NS_GetSessionToken
:获取一个有效期两年的session_token
NS_GetAccessToken
:基于session_token
获取一个有效期15分钟的access_token
NS_GetPlayHistory
:基于access_token
获取游戏记录信息
直接运行SwitchWebAPI.py调用NS_GetSessionToken
函数,该函数首先会返回一个授权页面链接,用户访问该链接登陆自己的NS账号,然后复制出授权重定向链接,粘贴回命令行窗口并回车输入,最终函数会返回session_token
。
将第一步获取的session_token
保存好,则可反复调用剩下两个接口获取游戏记录。
1 | import requests |
NS_GetPlayHistory返回数据格式
1 | { |
playHistories
包含了NS账户下所有游戏的历史统计记录,recentPlayHistories
包含近七天每一天的游戏时长统计记录。
需要注意的一点是,日服账号获取的返回数据中,时间是东九区时间,要转换为东八区北京时间需要减一个小时。
设计数据表
Switch数据表的设计与Steam数据表基本一致。因为使用日区账号获取的游戏数据名称都为日文,一种解决方案为使用游戏id在港服eshop页面爬取游戏中文名称,不过该名称为繁体中文,且在港服没有上架的游戏无法获取名称。因为我Switch上的游戏不会很多,所以就手动维护了一个中文译名表,在查询时关联使用。
dim_switch_game_play_history
字段 | 数据类型 | 备注 |
---|---|---|
titleId | varchar(255) | 游戏id |
titleName | varchar(255) | 游戏名称 |
deviceType | varchar(255) | 设备型号 |
imageUrl | varchar(255) | 游戏图标链接 |
lastUpdatedAt | datetime | 最近一次服务器数据更新时间 |
firstPlayedAt | datetime | 第一次游玩时间(开始时间) |
lastPlayedAt | datetime | 最近一次游玩时间(开始时间) |
totalPlayedDays | int | 总游玩天数 |
totalPlayedMinutes | int | 总游戏时长(分) |
create_time | datetime | 记录创建时间,默认值CURRENT_TIMESTAMP |
update_time | datetime | 记录修改时间,默认值CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP |
dwd_switch_game_played_record
字段 | 数据类型 | 备注 |
---|---|---|
id | int | 记录id,自增主键 |
titleId | varchar(255) | 游戏id |
titleName | varchar(255) | 游戏名称 |
lastPlayedAt | datetime | 最近一次游戏时间(开始时间) |
playtime | int | 游戏时长(分) |
create_time | datetime | 记录创建时间,默认值CURRENT_TIMESTAMP |
update_time | datetime | 记录修改时间,默认值CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP |
建表语句:1
2
3
4
5
6
7
8
9
10CREATE TABLE `dwd_switch_game_played_record` (
`id` int NOT NULL AUTO_INCREMENT,
`title_id` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL,
`title_name` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL,
`last_played_at` datetime DEFAULT NULL,
`play_time` int DEFAULT NULL,
`create_time` datetime DEFAULT CURRENT_TIMESTAMP,
`update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
dim_switch_game_name_translate_man
字段 | 数据类型 | 说明 |
---|---|---|
title_id | varchar(255) | 游戏id |
jp_name | varchar(255) | 日服游戏名称 |
zh_name | varchar(255) | 中文游戏名称 |
建表语句:1
2
3
4
5
6CREATE TABLE `dim_switch_game_name_translate_man` (
`title_id` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
`jp_name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,
`zh_name` varchar(100) COLLATE utf8mb4_general_ci DEFAULT NULL,
PRIMARY KEY (`title_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
数据采集
数据采集脚本
Swith游戏数据采集脚本的实现思路与Steam数据采集基本一致,要注意的是session_token
有两年的有效期,且获取该tocken时使用的client_id
一一对应。
1 | import json |
任务调度
使用腾讯云函数进行任务部署及调度的方案请参照这篇文章
调度方案与Steam数据采集一样,依然采用本地手动调度,通过快捷指令间接调用执行脚本。不过需要注意的是,Switch游戏数据上传到云服务器并没有Steam那么快,可能需要等几个小时才会同步。
sh脚本实现
1 | DA02_HOME_PATH=/your_path/data_acquisition_local |
快捷指令实现
快捷指令菜单栏效果
定时自动采集
配合Shortery实现定时任务,由于Switch服务器的数据更新有延迟,建议一天多采集几次数据。
报表效果展示
参考资料:
相关代码已托管于GitHub,欢迎Star!