使用python获取playstation奖杯数据 获取 token

微博   微信 4天前 14:50发布  江苏   29评论
exp
参考了 github 上通过 ps api 获取奖杯的方式,比较麻烦的部分是认证 token 的获取,github 项目关于这部分写的比较简单且使用的是 powershell 的方式。此处使用 python 重写了一遍,增加了 token 的刷新,部分 api 使用方式(翻译),文章底部会附上参考来源。

获取 token
1.1 获取 npsso
使用浏览器访问 playstation 官网登录账号(国服、港服都可以),之后在同一个浏览器(注意不要使用浏览器的无痕模式)中再访问 https://ca.account.sony.com/api/v1/ssocookie 获取 npsso。
1.2 获取 auth_code

import requests
from urllib.parse import parse_qs, urlparse

# 1.1 中获取的 npsso
npsso = "xrvW*****************************NYjq"
auth_url = "https://ca.account.sony.com/api/authz/v3/oauth/authorize"

# 固定参数
params = {
    "access_type": "offline",
    "client_id": "09515159-7237-4370-9b40-3806e67c0891",
    "response_type": "code",
    "scope": "psn:mobile.v2.core psn:clientapp",
    "redirect_uri": "com.scee.psxandroid.scecompcall://redirect",
}
auth_url += "?" + "&".join([f"{key}={value}" for key, value in params.items()])
response = requests.get(auth_url, cookies={"npsso": npsso}, allow_redirects=False)

# 请求的 status code 为 302,auth_code 在 response headers 中
if response.status_code == 302:
    location = response.headers.get("Location")
    query = parse_qs(urlparse(location).query)
    auth_code = query.get("code")[0]

1.3 获取 access_token 及 refresh_token

token_url = "https://ca.account.sony.com/api/authz/v3/oauth/token"

# 1.2 中获取的 auth_code
token_data = {
    "code": auth_code,
    "redirect_uri": "com.scee.psxandroid.scecompcall://redirect",
    "grant_type": "authorization_code",
    "token_format": "jwt",
}

# 请求头为固定内容
headers = {
    "Authorization": "Basic MDk1MTUxNTktNzIzNy00MzcwLTliNDAtMzgwNmU2N2MwODkxOnVjUGprYTV0bnRCMktxc1A=",
    "Content-Type": "application/x-www-form-urlencoded",
    "User-Agent": "PlayStation/21090100 CFNetwork/1126 Darwin/19.5.0",
}
response = requests.post(token_url, data=token_data, headers=headers)
response.raise_for_status()

# 请求成功后返回 access_token 及 refresh_token
access_token = response.json().get("access_token")
refresh_token = response.json().get("refresh_token")

access_token 时效只有 1 小时,refresh_token 的时效有 60 天,所以当 access_token 失效后,需要通过 refresh_token 来刷新 access_token。
1.4 刷新 access_token

token_url = "https://ca.account.sony.com/api/authz/v3/oauth/token"

# 1.1 中获取的 npsso
headers = {
    "Authorization": "Basic MDk1MTUxNTktNzIzNy00MzcwLTliNDAtMzgwNmU2N2MwODkxOnVjUGprYTV0bnRCMktxc1A=",
    "Cookie": f"npsso={npsso}",
    "User-Agent": "PlayStation/21090100 CFNetwork/1126 Darwin/19.5.0",
}

# 1.3 获取的 refresh_token
token_data = {
    "refresh_token": refresh_token,
    "scope": "psn:mobile.v2.core psn:clientapp",
    "grant_type": "refresh_token",
    "token_format": "jwt",
}
response = requests.post(token_url, data=token_data, headers=headers)
response.raise_for_status()

# 请求成功后获取 access_token
access_token = response.json().get("access_token")


评论
这个方式获取的奖杯数据信息,跟直接查用户有什么区别

P9好像是不用授权token就能查,授权查到的是跟PSApp里面一样吗?
incucc 4天前 17:42 广东
@incucc 如果有了token,可以查其他人或自己的数据。和psapp数据是一样的。api是从app中抓包拿到了。
zz-werke 3天前 14:33 江苏
如果有需要,日后可以直接使用psray项目的api
我们基于github上的一些psn-api项目,搭建一套公开的playstation api服务和网站,对于后续会对开发者免费提供
遗憾的是,现在没有时间来编写api文档,并且api会根据这边需求调整返回字段和请求参数,请不要用于正式的项目中

示例:例如需要获取个人资料,可以请求(请把最后替换成具体psnid)
https://api.psray.net/profile/get/abyssmoe
abyssmoe 前天 12:16修改 日本
所以这个网站是看奖杯吗?还是干嘛的
coffeebean0421 前天 10:39 广东
有这必要么
ssalor_1997 前天 10:59 北京
正好前段时间也在搞自己的奖杯页,踩了点坑,用的是这个项目 https://psn-api.achievements.app/
npsso 以及获取到的 access_code 是有时效的,如果一直从这边走会要定期手动更新 npsso
但是用 refresh_token 去获取 access_token 时,在满足一定条件下会自己续 refresh_token 的剩余时间,来达到完全自动化,具体可以看这个 https://psn-api.achievements.app/api-docs/authentication#exchangerefreshtokenforauthtokens

目前自己的奖杯页初步已经完成,主要为了能够自定义别名,同时显示别名和原名,并且可以自定义展示的奖杯组且支持排序,这样我给别人展示我某个系列的奖杯就可以直接发一个地址
unclesev 前天 14:06修改 上海
这个能获取游戏时长吗? 比如p9的在个人简介中输入特定字符,就可以获取,这种才方便
sephirothwkh 前天 12:49 四川
@sephirothwkh 楼主列出的几个api接口不可以。可以获取,当要用别的接口。
abyssmoe 前天 13:41 日本
扒数据最好就别明目张胆的发了
rookie926 前天 13:59 辽宁
@rookie926 虽然索尼没有像steam那样公开数据接口,并且在这方面限制和管理比较模糊暧昧。但是开源社区的大家,还是研究了些方法获取数据,方便开发者们为玩家构建一些psn游戏相关的app或事网站服务。先不管是否用来盈利了,大家都希望为ps社区宣传,为本来就少的psn社区吸引更多的玩家。
扯远一点,说真的我感觉国内ps群体的新人越来越少,只剩下老登了。去年我搬家的时候送了朋友一台ps5,然后他至今都没怎么开机过。身边的人也大多在玩手机游戏和pc游戏。希望有能力的人,给PS玩家提供更好更方便的交流地方和功能,让更多人接触入坑ps,这是我们的理想。
abyssmoe 前天 14:35 日本
上面的client_id和client_secret公开后,后来的人重新获取token,之前的不就失效了吗?
kongou233 前天 15:02 江苏
获取auth_code时报错有大佬知道原因么?
{
"error": "invalid_request",
"error_code": 4098,
"error_description": "Mandatory parameter 'client_id' is missing"
}
skyfantasyhong 前天 15:31 北京
@rookie926 这是索尼公开的api接口,公开api接口就是让大家进行合理调用的。和某些用Python无视规则扒数据还是有区别的,属于api的合法扩展应用
left_little_fox 前天 15:55 广西
@kongou233 client_id目前看是固定的参数,多年没有更新了。
zz-werke 前天 17:15 江苏
@abyssmoe 请教下,官方有获取游戏时长的借口吗?
zz-werke 前天 17:17 江苏
@left_little_fox 应该也不是索尼公开的,目前看应该是从ps app应用中抓包拿到的。
zz-werke 前天 17:20 江苏
@skyfantasyhong 1.1成功拿到npsso了吗,1.2中需要替换npsso变量。
zz-werke 前天 17:24 江苏
@unclesev 使用refresh_token刷新access_token后也会返回refresh_token。文章只是简单写了下逻辑,具体代码需要自己构建。
zz-werke 前天 17:34 江苏
@zz-werke 拿到npsso了,也加到header里了,但是一调就报错
skyfantasyhong 前天 18:02 北京
@abyssmoe 惭愧了,几年前在黑盒搞过主机社区,但是因为老板觉得来钱慢就不想做了。索尼也不想搞基本盘,坐吃山空可太正常了。不如说大部分人都觉得可持续发展是个笑话,而且是全方位的只考虑眼前和自己了。
srvenx-07 昨天 13:37 河北
@skyfantasyhong 是不是少了参数,我今天测试也是没问题的。看报错像是少了client_id。
zz-werke 昨天 14:19 江苏
@zz-werke 但是参数都填了啊,是哪里的问题呢
skyfantasyhong 昨天 15:14 北京
@skyfantasyhong 起码参数得齐全了吧
params = {
"access_type": "offline",
"client_id": "09515159-7237-4370-9b40-3806e67c0891",
"response_type": "code",
"scope": "psn:mobile.v2.core psn:clientapp",
"redirect_uri": "com.scee.psxandroid.scecompcall://redirect",
}
nikezhang 昨天 16:07 北京
@srvenx-07 没,其实终究是在说漂亮话而已,现实就是费力回报少。作为独立开发者,开发的越久,越是迷茫还要不要坚持下去。要不是几位可爱的群友精神上的支持,我可能放弃了。

在这里谢谢他们。
abyssmoe 昨天 16:33修改 日本
@nikezhang 是写全了的,只不过截图挡住了
skyfantasyhong 昨天 16:40 北京
@skyfantasyhong 换postman试试,apifox可能会不好用
palmsprings_ 昨天 17:08 山东
@palmsprings_ 请教一下,cookies的值是npsso={获取到的npsso}的格式么?
skyfantasyhong 昨天 17:39 北京
@skyfantasyhong 当使用GET Method的时候,参数应该填写在query中。你的这张截图的请求头部对应的是http headers,query参数是http query。如果填写在请求体(body)中。不会有效的
abyssmoe 昨天 19:13修改 日本
@skyfantasyhong 你如果用apifox的,这个请求响应是302没有response
zz-werke 12小时前修改 江苏
回复不能
T