SteamVR

SteamVR

Not enough ratings
利用R语言将Steam游戏数据上传到Notion并制成画廊
By ºd
R语言还能干这个?
   
Award
Favorite
Favorited
Unfavorite
摘要
※ 代码是在ChatGPT的大力帮助下完成的

※ 需要🪜

※ 灵感来源(如果你熟悉python和html,可以先看这个):
https://cs2bus.com/sharedfiles/filedetails/?id=3471694070
代码主要功能:
利用R语言自动抓取你的 Steam 游戏库信息,并上传至 Notion 数据库,包括游戏时长、成就、价格、商店标签、封面图等字段。

特点:
7.7更新
- 可在开头设置上传Notion的全局参数(config-2.R),更加方便地选择自己想要上传的内容
- 支持按需插入指定字段(如只想上传“游戏名称”, “游戏ID”, “游玩状态”, “游玩时间”, “游戏封面”)
- 现在可以将多个账号的数据合并上传到同一个Notion数据库(如果有需要)

- 支持 Steam API + 网页抓取,自动合并数据
- 可抓取成就、时长、最后游玩日期等信息
- 支持多字段上传到 Notion(如封面图、商店标签、游玩时间、最后游玩日期等)
- 支持按需更新字段功能(如只想更新“已解锁成就”、“游玩时间”等)
- 可选择自行选择是否上传DLC、Demo和原声音轨
- 可跳过网页抓取的游戏的不靠谱时间数据的更新
- 上传成功后可自动添加Steam图标
- 可初步判断游戏状态(游玩中、已弃坑等)
- 可导出 Excel
- 上传 Notion 进度提示(纯美观用)

存在问题:
- 由于我的部分游戏时长并非真实的,所以对游戏状态的判断整得很复杂,并且对于少部分游戏的游玩状态不一定准确,需要手动修改(觉得这个没用可以自行删掉)。
- 有小部分封面图片链接失效,正在考虑要不要加个后缀是”/main_capsule_616x353.jpg”的备选
- 由于部分仅能从网页抓取的数据不存在游玩时间的数据,所以仍需在Notion中手动添加

总而言之,代码并非完美,仍有需要在Notion中手搓的地方。尽管如此,也已极大减少了工作量,特别是当你初次构建Notion画廊但是又有几百个游戏的时候 ;-)
1. 前言
前几天备战夏促的时候,在Steam里看到了上面这个指南,想到自己当初搭建Notion的时候就是纯手搓的,一个个复制粘贴图片链接/上传图片差点没给我搞出腱鞘炎。而且随着库里找猫游戏的日益增多,我有时候也分不清+忘了这个100猫、那个猫100到底有没有被我记在Notion里,所以就试了试这个指南里方法。结果居然还挺顺利的,甚至我还试了试能不能再多提取几个信息,比如开发商和发行商,前者我F12找到元素名字通过模仿大法搞定了,后者虽然知道了名字但是因为不太了解Python和html语言,于是问了原本的指南作者,最后搞定了。

👇这是我之前的纯·手搓版,其实也挺满意的,毕竟花了很多时间(复制粘贴),真的是很有耐心呢()

👇在体验了数据抓取+手动上传CSV文件后,我四分之一自动搓出了我的第二版数据库(是的我就爱摸鱼干这个)

但我也发现了一个问题,那就是原本指南里的那个代码,它通过API抓取的数据并不全。比如API抓了313条游戏的数据,steam徽章又显示我有351款游戏,然后点进『https://cs2bus.com/id/我的id/games/?tab=all』里一看,显示我有500多个游戏???所以我到底有几个游戏???以及肉眼可见,有些游戏比如一些免费的《100 … Cats》就完全没被抓到,还是得手动补全。也不是不行,但就是感觉有点遗憾:都用自动化了我怎么还得一个个去复制粘贴封面链接!(没错我真的不想再复制粘贴那么多找猫游戏的链接了)

(比较搞笑的是我的API、网页、API+网页合并,这三个数据里的游戏数也没一个和之前抓的/徽章显示的/上面链接里的一样的)

然后我在搬(摸)砖(鱼)的时候就想,虽然我不了解Python和html,但是我略懂一点R语言啊!那么可不可以利用R语言来完成这件事呢?虽然也会用的自己不熟悉或者不懂的R包,但是这个语言环境至少是我熟悉的,可以减少一些陌生感。而且我突然想到:写代码这事不是还可以问AI嘛!与此同时我也想看看能不能抓到更全的数据。

总之说干就干(摸鱼爽),总之在各种调试(和疯狂询问ChatGPT)后,终于搓出了一份感觉能为第一次在Notion中搭建Steam游戏画廊的减轻负担的代码。总之,感谢ChatGPT!也谢谢给我灵感的指南作者kaikisen

那么,如何利用R语言抓取自己的Steam游戏数据,并批量上传到Notion上,然后较为快速地生成一个Notion画廊呢?请看下面:
2. 下载R以及RStudio(若有,可跳过)
RStudio主要是为R语言提供一个比较人性化的交互界面,以及集成了很多好用的功能。
RStudio是不能脱离R运行的。

首先,进入RStudio官网:RStudio Desktop[posit.co]

可以看到里面有很清晰的步骤展示怎么安装:


=> 2.1 下载R
顺着刚才官网里的指示,进入The Comprehensive R Archive Network[cran.rstudio.com]

然后根据自己的系统下载对应的版本,我是Win 11系统,所以下载R for Windows






下载好了之后运行安装!然后你的电脑里就有一个R了!
=> 2.2 下载RStudio
看到这个2: Install RStudio了吗?下载!安装!



安装好后,打开RStudio,界面大概如下:



好了,现在你可以使用RStudio了!
快来数据分析+作图吧!
3. 获取必须的配置信息
=> 3.1 获取Steam API、Steam ID
===>3.1.1 获取Steam API
点击:注册 Steam Web API 密钥

登录你的Steam账户,域名啥的随便写,然后注册 Steam Web API 密钥

(如果绑定了手机令牌,则需要在手机上二次确认一下)





这个密钥:<一串32位的数字和字母>就是你的Steam API Key

复制并保存下来。
===>3.1.2 获取Steam ID
进入Steam,点击账户明细xxxxxxxxx的账户



这个Steam ID:<一串17位的数字>,就是你的Steam ID

⚠️ 因为Notion可以手动导入CSV格式的表格,如果你对什么自动上传和自动更新没啥兴趣,只想先手动导入一个数据,可以先不管Notion API 和 Database ID的获取,直接看下一部分。
=> 3.2 获取Notion API、Database ID
===> 3.2.1 获取Notion API(可选)
点击进入:Notion集成[www.notion.so]

点击“新集成”

然后填写相关内容:





然后点击“配置集成设置”



这一串[被自动打码的内部集成密钥]就是你的Notion API,复制并保存


===> 3.2.2 获取Database ID(可选)
首先,在Notion中新建一个数据库一定要是数据库!

举个例子:





创建正确的话会显示“新表格”是“新表格”!


然后查看你建的这个数据库的链接,链接长这样:
https://www.notion.so/不重要的名字/<一串32位的数字和字母>?v=一串你别管的数字

那么这个?v=前面的<一串32位的数字和字母>就是你的Database ID

接下来,点击右上角的『· · ·』,点击『集成』,找到你刚才创建的新集成,然后确认连接。




好了,现在前期的准备工作就做好了,马上就能进入激动人心的扒数据环节了!
4. 导出Steam数据
现在你应该得到了如下4个信息
# === 必须获取的信息 ===
Steam API:<一串32位的数字和字母>
Steam ID:<一串17位的数字>

# === 如果只想手动导入,可不获取 ===
Notion API:<从Notion集成管理界面复制的一串数字和字母>
Notion Database ID:<一串32位的数字和字母>

⚠️ 注意,需要在隐私设置里公开自己的游戏详情(原理应该和小x盒、酱普之类的类似)


现在进入RStudio,将以下代码复制进去,然后在需要填写Steam API和Steam ID的地方填上你自己的,然后运行!(个人建议可以逐个函数运行,否则要是游戏多然后报错的话就很烦)

# 如果你想从GitHub[github.com]复制(0号、1号、2号、3号文件)
0 Important config.R[github.com]
1 packages.R[github.com]
2 Proxy (custom).R(这项看你网络环境)[github.com]
3 Steam to data.frame.R[github.com]


# 如果你想从Notion复制(1、2、3、4、5部分)
利用R语言将Steam游戏数据上传到Notion并制成画廊[www.notion.so]

如果一切顺利的话,你将看到👇

(✅表示这个游戏的相关信息抓取成功)
(⚠️信息表示这个游戏没在国区商店)
(❌信息表示在美区也没找到这游戏的信息)
(被迫把动图压成马赛克画质了,总之意会一下orz)

是不是还挺爽的?尤其是在摸鱼的时候!

当然我觉得其实原价、现价和折扣力度这种东西导出来除了徒增伤心(?)之外用处确实不大……因为你的购买价格和入库时间是不能通过这种方式抓取的(ChatGPT说的,如果有人会抓请分享!)

保存为Excel后,可以得到这么一张表:


内含各种信息:
  1. 游戏名称:若商店有中文名则优先显示中文名,英文名作为备注;无中文名则只显示英文名
  2. appid:游戏唯一id,steam游戏的身份证,对于后续的筛选有很大帮助
  3. 游玩时间:若不超过1小时,则显示…分钟;大于等于1小时则显示 …小时。若游戏数据来源仅为网页抓取,那么它的游玩时间通常是NA,需要在Notion中手动修改。
  4. 最后游玩时间:一个判断这个游戏是否弃坑的辅助信息。数据来源仅为网页抓取游戏没有这个信息,可以自己查阅<https://cs2bus.com/id/你的id/games/?tab=all>中的数据,然后在Notion中手动添加
  5. 成就总数&已解锁成就:计算成就进度,同时也可以辅助判断游戏的游玩情况
  6. 成就首次解锁于:API和网页都没有首次游玩日期,所以一些很久之前玩的游戏只能依靠首个成就解锁时间来辅助判断。
  7. 开发商&发行商&发售日期:顺手一抓,也可以借此建立黑名单/白名单
  8. 原价&当前价格&折扣:基本上只能让自己伤心的信息
  9. 标签:游戏商店界面的tag,用于筛选游戏。我只抓了前5个,想获取更多or更少,可修改#获取商店信息#里#提取商店标签#那部分的min(5, length(tag_nodes))里的数字。
  10. 来源:标记数据是来自API抓取、网页抓取,或是两者都有。同时也可用于Notion后续更新中识别仅网页抓取的数据。
  11. 内容类型:游戏本体、DLC、试玩版和原声音轨。上传Notion的时候也可以只上传游戏本体。
  12. 封面:游戏商店界面封面图的资源链接,可导入Notion使其变为画廊视图的卡片封面。
5. 将数据上传至Notion
=> 5.1 只想手动上传一次
如果你只想抓一次数据,然后剩余部分自己慢慢手搓,请将上面那部分导出的xlsx格式的表格另存为csv格式



(其实在R里面也可以直接保存为.csv格式,但不知道为啥有时候即使是路径里没中文,不论是用write.csv还是write_csv,写出来的文件里面的中文都会乱码,总之很神秘。)

总之保险起见,还是先存一个.xlsx格式的再另存为.csv吧

获得“Steam Data.csv”后,打开刚才建立的数据库。如果刚才没建,可以现在建,具体请看『3.3.2 获取Database ID』那部分。

在Excel表格里选取感兴趣的列,比如『游戏名称、游玩时间、已解锁成就数、成就总数、商店标签、发售日期、封面』,另存一个新的文件“Steam Data New.csv”(原始文件记得保存,以防出现意外)。然后根据这个“Steam Data New.csv”里的表头,在Notion数据库里逐一创建同样的表头:


⚠️注意:数据类型是文本的一定要在Notion中选则文本类型、数字选数字类型、日期选保险起见选择文本类型、封面由于是链接,所以选网址类型,诸如此类。


然后点击右上角的『· · ·』,选择与CSV合并,并选择上传刚才新建的“Steam Data New.csv”




然后点击导入就会有海量的游戏进入你的Notion数据库:


至此就算是完成了Steam数据的导入啦!

但是这样是不是看着有点丑?可以选择更改布局

先将封面的格式类型改成『文件与媒体』:



这样你的界面就会变成下图所示。


但还是不够美观对不对?

接下来将布局改为『画廊』格式,然后在『卡片预览』那一项选择『🔗封面』即可




商店标签也可以改为『多选』类型,方便日后筛选自己喜欢的游戏类型或者分组


那么现在,一个观赏性还不错的Notion游戏画廊就建好啦!

如果还有什么新的属性也可以自己添加,比如你对游戏的评分啥的,在下方空白处也可以写上自己对游戏的评价。

不过自己上传CSV文件的缺点就是:

如果日后想要再次上传,Notion并不会识别这个游戏你之前是否已经上传过,所以会重复上传。除非自己手动在上传之前去掉Notion中已有的游戏(但这样就不能更新其它信息了,比如游玩时间、已解锁成就数的变化等等。而且还有一个就是你得把商店标签那里的『多选』类型改回『文本』类型,否则就会出问题。

所以有没有一种方式能够更加智能地上传Steam数据、减少手搓、对已有游戏只进行更新、避免重复上传呢?

有的,那必须有的。请看下面:
=> 5.2 通过R随时更新
首先,将上传Notion的代码复制进R里,并将你自己的Notion API和Database ID填入

代码如下:
# 如果你想从GitHub[github.com]复制(继续复制4号、5号文件;上传时根据自己需要选择6-1还是6-2)
4 config-2.R[github.com]
5 df2Notion utils.R[github.com]
6-1 upload (single user).R[github.com] <=== 一个账号选这个
6-2 upload(multi_users).R[github.com] <=== 多个账号选这个

# 如果你想从Notion复制(第6部分)
利用R语言将Steam游戏数据上传到Notion并制成画廊[www.notion.so]

然后依旧需要根据你所要上传的内容,在Notion数据库里一一创建条目。

游玩状态要选择『状态』类型.

并且由于游玩状态是依据游玩时间、成就进度等参数判断的,在原本的数据框(即代码里的final_df)中并不存在,所以要预先在Notion中按照上传代码中的几个状态设置好,比如:



以及即将要上传的这些字段在Notion中的属性分别是:






好了,准备工作已经做好,现在可以准备上传了!

以防你忘记👇,记得把之前获得的Notion API和Database ID填到复制好的代码里

notion_token <- "你的Notion Integration Token(API),保留双引号"
database_id <- "你的32位Notion Database ID,保留双引号"

然后运行!

不出意外的话就能看到如下盛况:

(动图不能超过2mb大家就意会一下吧orz)

对于在Notion中不存在的游戏,会显示:


对于Notion中已存在的游戏,会更新自定义的条目,比如解锁成就数、游玩时间等


对于数据来源仅为网页抓取的游戏,更新的时候选择不更新“游玩时间”


对于非游戏本体,比如DLC、试玩版和原声音轨,上传的时候可以选择跳过


上传完成后,会显示一个用时来增加可能存在的仪式感


好了,如果没有发生⚠️、或者更可怕的❌的话,就证明你的数据安全上传啦!

虽然⚠️警告不是❌报错,出现⚠️警告未必会有很大影响,但还是建议可以设置options(warn = 1),这样每条警告都能即时知道
6. 打理Notion游戏库
数据上传完毕后,在Notion中大概就是这么个样子:

(真的有很多......猫!)

点开一个游戏的话里面是这样的:
=> 6.1 成就进度装饰
上面展示的这个成就进度我是在Notion里用函数写的,挺简单的。觉得我这个还不错的话可以直接抄作业😉
if(prop("已解锁成就")/prop("成就总数") == 1, "■■■■■■■■■■ 🏆", if(empty(prop("成就总数")), "此版本无成就", ((substring("■■■■■■■■■■", 0, floor(prop("已解锁成就")/prop("成就总数") *10)) + substring("☐☐☐☐☐☐☐☐☐☐", floor(prop("已解锁成就")/prop("成就总数") *10))+ " ")+ format(round(prop("已解锁成就")/prop("成就总数") *100))) + "%"))
=> 6.2 其它属性和装饰
除开从Steam那里抓来的数据,我们在Notion中也可以像添加成就进度函数一样自行添加各种属性。

比如说你想对主角性别进行分类写一句简评添加游玩年份和游戏平台以备后续分组等等,这都是完全OK的。

比如👇

对商店自带的标签不满意?改!👇


想对某个游戏系列分类?分!👇


当然,我对Notion最喜欢的一点是:在Notion中可以直接在每个游戏条目的下方空白处写短评/长评,非常方便,不用担心Steam偶尔网络抽风评测发布失败。




可能你还会好奇为什么我的游戏卡片标题前面有一个平台图标?

除开我通过R语言自动上传的Steam图标,你也可以自己在标题位置添加自定义图标,位置在:


添加自定义图标有助于区分多平台游戏,特别是同一个游戏在不同平台上都有购买这种情况。

当然,在写一些感想的时候也能为文章添加图标,增加……增加自己的快乐?

总结
总而言之,个人认为将Steam(以及其它平台)游戏的数据记录在Notion中、并添加一些自定义属性来方便自己分类筛选,是一个让自己游戏过程变得更加可视化(?)的方式。

如果你想尝试搭建一个布局成画廊样式的Notion游戏库,并且你略懂或很熟悉R语言,那么你可以来试一试我这个方式~

如有错误请指正。