好友
阅读权限25
听众
最后登录1970-1-1
|
厄斐琉斯
发表于 2020-7-31 23:11
本帖最后由 厄斐琉斯 于 2020-7-31 23:19 编辑
特别鸣谢:感谢Hatsune_miku前辈在github上开源的部分源码
声明:任何人不得将其用于任何商业目的,否则后果自负!
前言:之前在论坛上看到过一篇获取B站弹幕的帖子,作者只是给出了成品和部分关键的源码,但是没有讲解,源码也没有注释,我在网上搜了一下找到了B站官方提供的弹幕接口api:'https://comment.bilibili.com/' + cid + '.xml',然后通过分析api返回的各项数据以及结合CSDN、github、吾爱上各位前辈零零星星的讲解把这个过程复现了一下。
一、获取cid值
1.1、什么是cid值?
cid值是B站每个视频特有的编号,一个av或者BV号下允许含有多个子视频,但是一个cid号只对应一个视频1.2、如何获取cid值?
在B站视频网站界面按下ctrl+u查看页面源代码,按下ctrl+F搜索,输入cid进行查找即可,页面中可能含有多个cid值,需要根据文字内容找到对应视频的cid值
1.3、示例
我选取了s8总决赛ig对战FNC第三局的视频进行示范,BV号14b411w7La,av号35199206,通过ctrl+u加上ctrl+F搜索cid查找可得cid值为61697318,如图
二、访问接口获得相应数据接口
api为'https://comment.bilibili.com/' + cid + '.xml',假设cid使用上面获得的值,则网址为https://comment.bilibili.com/61697318.xml,访问网址可以看到下图
这只有弹幕文字内容,同样地,按下ctrl+u加上ctrl+F,随便搜索一条文字信息,例如“我们是冠军!”,可以找到下图的内容
这条信息<d p="1925.92700,1,25,16777215,1589174749,0,1885b1b1,32522934504390661">我们是冠军!!!!!</d>的内容是什么意思呢?
首先,弹幕文字内容为我们是冠军!!!!!,然后p="1925.92700,1,25,16777215,1589174749,0,1885b1b1,32522934504390661"里的这一堆参数,第一个为弹幕出现距离视频开始的秒数,第二个是弹幕的模式,第三个是弹幕的字号,第四个是弹幕的颜色,第五个是弹幕发送的unix时间戳,可通过https://tool.chinaz.com/Tools/unixtime.aspx该网站转换成年月日时分秒的格式,第六个是弹幕池,第七个是发送弹幕者的hash_uid,第八个是弹幕发送者的历史弹幕记录这里面我们要的是第七个:弹幕发送者的hash_uid
三、hash_uid转uid
3.1、什么是hash_uid和uid?
uid是B站每个用户的ID编号,独一无二,访问https://space.bilibili.com/{uid}即可看到该用户的个人主页,而hash_uid是uid的哈希值
3.2、hash_uid如何转成uid?
哈希值没有逆向直接解的方法,只能使用查表的方法,因为uid值目前都是8位或9位纯数字(8位为主),所以可以写一个大循环遍历查找
3.3、uid转hash_uid的算法教程
C语言版:https://blog.csdn.net/gongmin856/article/details/77101397
python版:https://www.jianshu.com/p/6e54a562fc5c
3.4、实例
例如我们需要计算1885b1b1的uid原值,可以写一个大循环for(i=0;i<100000000;i++)的形式找,找到的结果为xxxxxxxx(涉及个人信息,这里不便公布)然后访问https://space.bilibili.com/xxxxxxxx即可看到个人主页
四、用途
有的时候看B站的视频会看到一些引战、尬黑的弹幕,之前想举报不知道对方是谁,通过这种方法可以查到对方uid然后举报给B站后台。论坛上有前辈开玩笑地说可以顺着屏幕找对方对线hhhhhhh,不过讲道理一般而言也没人会这么干,除非自己发的视频被别人发了恶意弹幕
五、hashuid转uid的python源码
本源码为Hatsune_miku前辈在Github上开源,任何人转载需声明版权
[Python] 纯文本查看 复制代码 CRCPOLYNOMIAL = 0xEDB88320
crctable = [0 for x in range(256)]
def create_table():
for i in range(256):
crcreg = i
for _ in range(8):
if (crcreg & 1) != 0:
crcreg = CRCPOLYNOMIAL ^ (crcreg >> 1)
else:
crcreg = crcreg >> 1
crctable[i] = crcreg
def crc32(string):
crcstart = 0xFFFFFFFF
for i in range(len(str(string))):
index = (crcstart ^ ord(str(string)[i])) & 255
crcstart = (crcstart >> 8) ^ crctable[index]
return crcstart
def crc32_last_index(string):
crcstart = 0xFFFFFFFF
for i in range(len(str(string))):
index = (crcstart ^ ord(str(string)[i])) & 255
crcstart = (crcstart >> 8) ^ crctable[index]
return index
def get_crc_index(t):
for i in range(256):
if crctable[i] >> 24 == t:
return i
return -1
def deep_check(i, index):
string = ""
tc=0x00
hashcode = crc32(i)
tc = hashcode & 0xff ^ index[2]
if not (tc <= 57 and tc >= 48):
return [0]
string += str(tc - 48)
hashcode = crctable[index[2]] ^ (hashcode >>8)
tc = hashcode & 0xff ^ index[1]
if not (tc <= 57 and tc >= 48):
return [0]
string += str(tc - 48)
hashcode = crctable[index[1]] ^ (hashcode >> 8)
tc = hashcode & 0xff ^ index[0]
if not (tc <= 57 and tc >= 48):
return [0]
string += str(tc - 48)
hashcode = crctable[index[0]] ^ (hashcode >> 8)
return [1, string][/size]
[size=4]
[/size]
[size=4]def getuid(string):
create_table()
index = [0 for x in range(4)]
i = 0
ht = int(f"0x{string}", 16) ^ 0xffffffff
for i in range(3,-1,-1):
index[3-i] = get_crc_index(ht >> (i*8))
snum = crctable[index[3-i]]
ht ^= snum >> ((3-i)*8)
for i in range(100000000):
lastindex = crc32_last_index(i)
if lastindex == index[3]:
deepCheckData = deep_check(i, index)
if deepCheckData[0]:
break
if i == 100000000:
return -1
return f"{i}{deepCheckData[1]}"
六、hashuid转uid的exe成品
我根据Hatsune_miku前辈的python算法用C语言做出了exe,效率更快
hashuid_to_uid.zip
(10.99 KB, 下载次数: 114)
七、改进版完整成品
上述所用方法单个视频最多只能获得1500条弹幕,要想获取完整弹幕及其发送者信息需要网页分析获得,我之前做过一个exe程序可以获得完整版弹幕(亲测上万条弹幕运行正常),有空发上来,敬请期待
|
免费评分
-
查看全部评分
|
发帖前要善用【论坛搜索】功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。 |
|
|
|
|