作为b站老粉丝,我有义务向新人科普bilibili的发展与纪年史,本人持中立态度,仅做记录工作。
B站的API端口都是开放的,用一个很简单的调用命令就可以计算出BV号对应的AV号。
B站的源码已经在GitHub上流出,部分机制甚至还没有经过修改。
尊敬的各位用户:一直以来,AV 号都是 B 站视频稿件的重要标识,在视频的传播和分享中起到了关键作用。为了保护稿件信息安全,容纳更多投稿,维护 UP 主的权益,自 年 3 月 23 日起,AV 号将全面升级为 BV 号。与纯数字的 AV 号不同,BV 号是一段由数字和大小写字母组成的字符串,经过算法自动生成。未来将统一使用 BV 号作为稿件标识。同时, 年 3 月 23 日前生成 AV 号的相关功能保持不变。例如,已分享的稿件链接,AV号搜索,以及动态、评论、私信中的高亮跳转。此外,用户在复制 BV 号或者包含 BV 号的链接后,打开 B 站 APP 的同时会自动跳转至该视频。
1. BV与AV号互换
python源代码:
table='fZodR9XQDSUm21yCkr6zBqiveYah8bt4xsWpHnJE7jL5VG3guMTKNPAwcF'tr={}for i in range(58):tr[table[i]]=is=[11,10,3,8,4,6]xor=177451812add=8728348608def dec(x):r=0for i in range(6):r+=tr[x[s[i]]]*58**ireturn (r-add)^xordef enc(x):x=(x^xor)+addr=list('BV1 4 1 7 ')for i in range(6):r[s[i]]=table[x//58**i%58]return ''.join(r)print(dec('BV17x411w7KC'))print(dec('BV1Q541167Qg'))print(dec('BV1mK4y1C7Bz'))print(enc(170001))print(enc(455017605))print(enc(882584971))
运行结果测试为:
170001 ==> BV17x411w7KC
455017605 === > BV1Q541167Qg
2. bilibili的弹幕api接口
bilibili的弹幕api接口主要通过如下方式来获取弹幕:
获取cid编码
通过请求 /x/player/pagelist?bvid=BV号&jsonp=jsonp 这个接口,返回为json数据类型,提取其中的cid返回值
获取xml的弹幕列表
接下来在通过请求 /x/v1/dm/list.so?oid=返回的cid值,返回值为xml数据类型,正则表达式提取出文本内容,便是我们需要的弹幕列表
python源代码:
# -*- coding:utf-8 -*-import reimport jiebaimport numpy as npimport requestsfrom PIL import Imagefrom wordcloud import WordCloudfrom matplotlib import pyplot as plt"""获取哔哩哔哩弹幕"""# BV下载页面def download_page(url):try:headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36"}result = requests.get(url=url, headers=headers, timeout=10)if result.status_code == 200:return resultexcept Exception as e:print(e)# 获取cid编码def get_cid(Bv):url = '/x/player/pagelist?bvid={}&jsonp=jsonp'.format(Bv)response = download_page(url)res_dict = response.json()cid = res_dict['data'][0]['cid']return cid# 根据cid请求弹幕def get_dan_mu(cid):url = '/x/v1/dm/list.so?oid={}'.format(cid)res = download_page(url)res_xml = res.content.decode('utf-8')pattern = pile('<d.*?>(.*?)</d>', re.S)dan_mu_list = re.findall(pattern, res_xml)return dan_mu_list# 把弹幕写入到文件中def save_to_file(dan_mu_list):with open('./{}.txt'.format(bv), mode='w', encoding='utf-8') as f:for i in range(len(dan_mu_list)):# 将列表中的每个数去除首尾空格后,逐行写入txt文件f.write(str(dan_mu_list[i]).strip() + '\n')# 弹幕爬虫主流程def main(bv):# 根据视频av号获得cidcid = get_cid(bv)# 根据cid爬取弹幕dan_mu_list = get_dan_mu(cid)# 把弹幕写入到文件中save_to_file(dan_mu_list)if __name__ == '__main__':bv = str(input("请输入目标BV号:BV17x411w7KC")).strip()main(bv)