做一个自动管理 b 站的程序,帮助我们快速批量创建收藏夹,收藏视频(懂得都懂)
一、自动登录 bilibili
首先需要获取到账号的 Cookie,目前还没有实现自动获取,暂时先使用了哔哩哔哩粉丝牌助手提供的 Cookie 获取工具。
获取到 Cookie 后,就可以对 session 进行配置
self.session = requests.session()
self.session.cookies['DedeUserID'] = # uid
self.session.cookies['DedeUserID__ckMd5'] = #
self.session.cookies['SESSDATA'] = #
self.session.cookies['bili_jct'] = #
self.session.cookies['LIVE_BUVID'] = #
self.headers = {
'origin': 'https://space.bilibili.com',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4501.0 Safari/537.36 Edg/91.0.866.0',
}
接下来测试一下能否成功登录,注意 CookieException
是我自定义的异常。
# url 是个人空间的收藏夹管理页面
url = 'https://space.bilibili.com/%s/favlist' % self.uid
homePage = self.session.get(url, headers=self.headers)
if (self.session.cookies['DedeUserID'] == '' or self.session.cookies['DedeUserID__ckMd5'] == ''):
# 如果没有配置 Cookie 文件
raise CookieException(0, 'Please configure the Cookie in the init method')
else:
home_page = homePage.content.decode("utf-8")
if ('个人空间_哔哩哔哩_Bilibili' not in home_page):
# 没有成功 get 到页面,说明 Cookie 配置有问题
raise CookieException(1, 'Invalid Cookie.')
user_name = re.findall(r'<meta name="keywords" content="(.*),B站', home_page)[0]
print('Valid Cookie, user name: %s' % user_name)
成功运行之后如下所示:
二、收藏夹管理
由于时间关系,我打算先完成对收藏夹的操作,之后再完善对收藏视频的操作
2.1 创建新收藏夹
创建收藏夹是所有操作中最基本的功能,实现了这个操作后,后面的操作大同小异。
通过抓包,可以发现创建收藏夹的 api 接口为 https://api.bilibili.com/x/v3/fav/folder/add
,其数据为:
{
"title": "folder title",
"intro": "folder introduction",
"privacy": 0, //0 为公开,1 为私密
"cover": "cover image link",
"csrf": "70e8a10f9998293cdb639fa52bacf3ab", //固定值
}
只需要向接口 post 对应的数据,即可实现新建收藏夹。对于 post 返回的数据,有两个比较重要,分别是 code
错误代码和 message
错误信息。
check = self.session.post(url, headers=self.headers, data=data).json()
if check['code'] != 0: # code = 0 运行成功
raise FavlistException(1, check['message'])
print('The folder has been created successfully.')
2.2 获取收藏夹列表
为了更方便的对收藏夹进行管理,我们需要一个方法来获取所有的收藏夹,并形成一个表。
同样通过抓包我们找到了它的 api https://api.bilibili.com/x/v3/fav/folder/created/list-all?up_mid=
,等号后面接自己的 uid。
之后通过 get 可以获取一个 json 形式的数据,经过观察,可以找到所有收藏夹的信息。
check = self.session.get(url).json()
if check['code'] != 0:
raise FavlistException(3, check['message'])
favList = check['data']['list']
return favList
顺便写一个方法来打印出所有的收藏夹
def printFavlist(self, favList):
print("\tid\t\tfid\t\ttitle\t\tmedia_count")
for k, i in enumerate(favList):
print('%s\t%10s\t%8s\t%s\t%s' % (k, i['id'], i['fid'], i['title'], i['media_count']))
2.3 获取单个收藏夹信息
前面获取所有收藏夹信息的方法只能获得它们大概的信息,而接下来我们要获取某个收藏夹的详细信息。
它的 api 看起来略有不同,但是用法都一样 https://api.bilibili.com/x/v3/fav/resource/list?media_id=%s&pn=1&ps=20&keyword=&order=mtime&type=0&tid=0&platform=web&jsonp=jsonp
中间 %s
是收藏夹的 id
同样使用 get 方法获取数据,再从中挑选出有用的信息
check = self.session.get(url, headers=self.headers).json()
# 我们要挑出的信息
keys = ['id', 'fid', 'title', 'cover', 'cnt_info', 'intro', 'media_count']
# 文件夹信息在 data 下的 info 中
check = check['data']['info']
info = {}
for i in keys:
info[i] = check[i]
return info
在获取某个收藏夹之前,我们可以先判断一下该收藏夹存不存在
mediaList = self.getFavlist()
for i in mediaList:
if i['id'] == mediaId:
return
raise FavlistException(4, "Can not find the folder")
2.4 修改收藏夹信息
和新建收藏夹一样,先获取 api 和需要 post 的数据 https://api.bilibili.com/x/v3/fav/folder/edit
{
"title": "lxymyxdd",
"intro": "this is a test message",
"privacy": 0,
"cover": "",
"csrf": "70e8a10f9998293cdb639fa52bacf3ab", //固定值
"media_id": 1607747941, //收藏夹 id
}
但值得注意的是,如果不想修改原先的数据,则对应的值应该填入原先的数据,而不是什么都不填,这就需要用到刚刚写好的获取收藏夹信息的方法了。
url = r'https://api.bilibili.com/x/v3/fav/folder/edit'
raw_data = self.getFolderInfo(mediaId)
data = {
"privacy": 0,
"csrf": "70e8a10f9998293cdb639fa52bacf3ab",
"media_id": mediaId,
}
data['title'] = raw_data['title'] if title == None else title
data['intro'] = raw_data['intro'] if intro == None else intro
data['cover'] = raw_data['cover'] if cover == None else cover
check = self.session.post(url, headers=self.headers, data=data).json()
if check['code'] != 0:
raise FavlistException(6, check['message'])
print("The information has changed successfully.")
2.5 删除收藏夹
和创建收藏夹一样,没有需要特别说明的。直接贴出 api https://api.bilibili.com/x/v3/fav/folder/del
{
"media_ids": ,//收藏夹 id
"platform": "web", // 都是固定数据
"jsonp": "jsonp",
"csrf": "70e8a10f9998293cdb639fa52bacf3ab",
}
check = self.session.post(url, headers=self.headers, data=data).json()
if check['code'] != 0:
raise FavlistException(3, check['message'])
print('The folder has been deleted successfully.')
2.6 修改收藏夹的顺序
在管理收藏页面,我们发现按住收藏夹右边部分并拖动可以更改它所在的位置,这一功能虽然用处不大,但是我也实现了一下。
依然是抓包获取 api 和数据 https://api.bilibili.com/x/v3/fav/folder/sort
{
"sort": "156985141,1328013241,1194508841", //收藏夹 id
"jsonp": "jsonp", //这些都是固定值
"csrf": "70e8a10f9998293cdb639fa52bacf3ab",
}
观察一下我们可以发现,收藏夹的顺序就是 sort
下 id 的顺序,由此我们就可以写出该功能。其中 mediaId
为要移动的收藏夹的 id,index
是要移动到的位置。
favList = self.getFavlist()
idList = []
for k, i in enumerate(favList):
idList.append(i['id'])
idList.remove(mediaId)
try:
idList.insert(index, mediaId)
except IndexError as ie:
idList.append(mediaId)
print("Index out of range, it will be moved to the bottom of the list")
idstr = ""
for i in idList:
idstr += str(i) + ","
check = self.session.post(url, headers=self.headers, data=data).json()
if check['code'] != 0:
raise FavlistException(7, check['message'])
print('The folder has been moved successfully.')
魔改一下这个方法就可以实现收藏夹按指定顺序排序,这里就不做拓展了。
目前仅开发了这几个功能,之后要去忙期末所以不一定有时间继续开发,等暑假吧。