哔哩哔哩投稿工具抓包分析
很久之前说过, B站转载视频是放在服务器上托管了, 也一直再用一个叫做bilibiliupload的包. 经过几次改版, 部分接口需要改动, 可能是作者没有时间维护这个包, 导致部分功能失效, 准备着手自己抓包看看.
准备
其实还有个原因, 2021年呢, 准备做个全职UP主, 所以不但算在主账号上发布转载视频了, 但是也不想放弃这个转载视频(关注的人不多, 但是不少用户还是会求更新的), 就在小号中转载, 但是这个账号吧, 在网页端不支持分P, 转载视频一般都用添加分P来规避专车检查.
之前用的这个包, 上传部分用的就是网页端接口, 于B站客服沟通得知, 说是网页端更新导致, 使用投稿工具就可以分P了. 所以就自己造个轮子吧.
- Proxifier
- Fiddler 或 Charles
Proxifier用来使投稿工具走代理, Fiddler 或 Charles 负责抓包.
分析
具体抓包过程就不发截图了, 因为都没有什么难点, 只要这几个工具都知道怎么使用(基础操作)就行了. 有需要可以在评论回复.
登录
这部分就两个POST请求, 先获取用来加密的公钥以及盐, 接着访问登录接口就好了.
POST https://passport.bilibili.com/api/oauth2/getKey
#参数
appkey aae92bc66f3edfab
platform pc
sign 89c2f1e93c09fedd2a1c5f0a3a678326
ts 1610018294
appkey可以理解为是用来区分客户端的, 几乎所有操作请求都需要这个参数. platform就是平台的意思, 这类参数一般不用考虑默认就行. sign是对整个请求的参数进行加盐后MD5的校验值. 这个盐和appkey是对应的每个客户端一对, 具体可以在这里查看: https://github.com/SocialSisterYi/bilibili-API-collect/blob/master/other/API_auth.md, ts不多说了时间戳.
#返回数据
{
"ts": 1610018294,
"code": 0,
"data": {
"hash": "0cff56e2df266d5b",
"key": "-----BEGIN PUBLIC KEY-----xxxxxxx-----END PUBLIC KEY-----\n"
}
}
返回数据data中, hash就是盐, hash+密码之后的值进行rsa加密, 加密所需的公钥就是另一个数据key.
POST https://passport.bilibili.com/api/v3/oauth2/login
#参数
appkey aae92bc66f3edfab
password 3oQkoLueIK1xxxx
platform pc
sign a8b948458bf2e11da33dfda14717b7e1
ts 1610018295
username xxxxxxx
和上面唯一不通的就是username、password, 用户名和密码, 用户名是明文, 密码就是上面所说的加密方式.
{
"ts": 1610018295,
"code": 0,
"data": {
"status": 0,
"token_info": {
"mid": 729739818,
"access_token": "c7f172ea71144cb922ead8bd2e86155e",
"refresh_token": "a737bdf10f504fc299d2ed34e03a337d",
"expires_in": 2592000
},
"cookie_info": {},
"sso": []
}
}
返回值中就当前的功能我们所需的就是token_info中的四个属性值. mid用户ID, access_token请求令牌, 有了这个令牌就有了整个账户的控制权限. refresh_token刷新令牌, 就是为了刷新请求令牌用的, expires_in就是请求令牌的时效, B站的令牌一般都是30天, 所以快到30天的时候可以用refresh_token来刷新令牌. 其余的cookie_info和sso是有值的, 只是用不上就不说讲.
这两个请求需要注意的就是, 请求头Content-Type: application/x-www-form-urlencoded, 以及一个空白的User-Agent. 另外就是getKey的请求会生成一个Cookie: sid=xxxxxxxx, 这个建议带上.
上传视频
这部分三个请求, 预上传, 上传, 添加视频
预上传
GET http://member.bilibili.com/preupload
access_key c7f172ea71144cb922ead8bd2e86155e
mid 729739818
profile ugcfr/pc3
预上传, access_key和mid分别是上一步登录成功获取的请求令牌以及用户ID, profile可能是上传工具的一个标志吧, 不用改变原封不动添加上就行.
{
"complete": "http://upcdn-szqn.bilivideo.com/vs814/xxxxx",
"OK": 1,
"url": "http://upcdn-szqn.bilivideo.com/xxxx5",
"filename": "xxxxxxxxxxxxxxxxxxx"
}
返回值, OK代表状态, 不是1就说明出现错误了. url就是下一步视频上传所需要的地址, complete是上传完毕的请求, 告诉服务器之前的视频(分片)传完了. filename是服务器中的文件名字, 后续添加视频的时候要用到.
上传视频
上传就用截图解释了, POST请求, 地址就是预上传请求返回的url, Content-Type为 multipart/form-data. 发送参数如下.
返回值如果正常上传只有两个返回值, {"OK": 1, "info": "Successful."}.
上传完毕通知
POST http://upcdn-szqn.bilivideo.com/vs814/xxxxxxxxxx
chunks 75
filesize 155245475
md5 a975ee0a86c1460e074ba3fd604157f4
name xxxxx.mp4
version 2.2.0.1057
上传完毕的通知请求, chunks文件块的数量, filesize文件大小, md5文件MD5, name本地文件名, version上传工具版本号. 其请求正常返回值也是只有OK 和 info两个参数.
添加视频
POST http://member.bilibili.com/x/vu/client/add
access_key c7f172ea71144cb922ead8bd2e86155e
sign 8354da9b8dc51f2051d9cb844e060265
{
"build": 1057,
"copyright": 2,
"cover": "http://i0.hdslb.com/bfs/archive/424ff37639d5cd727b222bea87af5761ee624b20.png",
"desc": "youtube",
"no_reprint": 0,
"open_elec": 1,
"source": "转载来源",
"tag": "\u82F1\u96C4\u8054\u76DF",
"tid": 171,
"title": "视频标题",
"videos": [
{
"desc": "",
"filename": "xxxxxxxxxxxx",
"title": "P1视频标题"
},
{
"desc": "",
"filename": "xxxxxxxxxxxx",
"title": "P2视频标题"
}
]
}
具体参数的解释可以查看文末提供的Python代码, 已经分享到GitHub Gist上面了. 也是目前正在使用的上传脚本.
{
"code": 0,
"message": "0",
"ttl": 1,
"data": {
"aid": 288600734,
"bvid": "BV1hf4y1y75f"
}
}
返回值一目了然 两个ID, 现在用的就是BV了.
成品
Python编写的脚本, 使用到的第三方模块只有requests. 脚本中还提到了预览图上传以及刷新token的功能.
地址: https://gist.github.com/Virace/f6036bfd2baa8129ec6b142230b10924
注释感觉挺多的, 如果有什么问题可以在本文下方评论反馈, 也可以在Github上反馈.
整体分析过程没什么难度, 因为已经有前人铺路了, 很多轮子都有. 比如说参数签名等. 而且在上传工具登录过程中没有出现过验证码, 如果出现了验证码, 那就手动处理一下验证码, 后续只用刷新token就可以了.
文章评论