作为b站老粉丝,我有义务向新人科普bilibili的发展与纪年史,本人持中立态度,仅做记录工作。
B站的API端口都是开放的,用一个很简单的调用命令就可以计算出BV号对应的AV号。
B站的源码已经在GitHub上流出,部分机制甚至还没有经过修改。
尊敬的各位用户:
一直以来,AV 号都是 B 站视频稿件的重要标识,在视频的传播和分享中起到了关键作用。
为了保护稿件信息安全,容纳更多投稿,维护 UP 主的权益,自 2020 年 3 月 23 日起,AV 号将全面升级为 BV 号。
与纯数字的 AV 号不同,BV 号是一段由数字和大小写字母组成的字符串,经过算法自动生成。未来将统一使用 BV 号作为稿件标识。
同时,2020 年 3 月 23 日前生成 AV 号的相关功能保持不变。例如,已分享的稿件链接,AV号搜索,以及动态、评论、私信中的高亮跳转。
此外,用户在复制 BV 号或者包含 BV 号的链接后,打开 B 站 APP 的同时会自动跳转至该视频。
python源代码:
table='fZodR9XQDSUm21yCkr6zBqiveYah8bt4xsWpHnJE7jL5VG3guMTKNPAwcF'
tr={}
for i in range(58):
tr[table[i]]=i
s=[11,10,3,8,4,6]
xor=177451812
add=8728348608
def dec(x):
r=0
for i in range(6):
r+=tr[x[s[i]]]*58**i
return (r-add)^xor
def enc(x):
x=(x^xor)+add
r=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
bilibili的弹幕api接口主要通过如下方式来获取弹幕:
获取cid编码
通过请求 https://api.bilibili.com/x/player/pagelist?bvid=BV号&jsonp=jsonp 这个接口,返回为json数据类型,提取其中的cid返回值
获取xml的弹幕列表
接下来在通过请求 https://api.bilibili.com/x/v1/dm/list.so?oid=返回的cid值,返回值为xml数据类型,正则表达式提取出文本内容,便是我们需要的弹幕列表
python源代码:
# -*- coding:utf-8 -*-
import re
import jieba
import numpy as np
import requests
from PIL import Image
from wordcloud import WordCloud
from 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 result
except Exception as e:
print(e)
# 获取cid编码
def get_cid(Bv):
url = 'https://api.bilibili.com/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 = 'https://api.bilibili.com/x/v1/dm/list.so?oid={}'.format(cid)
res = download_page(url)
res_xml = res.content.decode('utf-8')
pattern = re.compile('(.*?)' , 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号获得cid
cid = 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)