厄斐琉斯 发表于 2020-7-31 23:11

【原理讲解附源码】找到B站弹幕的发送者

本帖最后由 厄斐琉斯 于 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上开源,任何人转载需声明版权
CRCPOLYNOMIAL = 0xEDB88320
crctable =

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 = crcreg

def crc32(string):
    crcstart = 0xFFFFFFFF
    for i in range(len(str(string))):
      index = (crcstart ^ ord(str(string))) & 255
      crcstart = (crcstart >> 8) ^ crctable
    return crcstart

def crc32_last_index(string):
    crcstart = 0xFFFFFFFF
    for i in range(len(str(string))):
      index = (crcstart ^ ord(str(string))) & 255
      crcstart = (crcstart >> 8) ^ crctable
    return index

def get_crc_index(t):
    for i in range(256):
      if crctable >> 24 == t:
            return i
    return -1

def deep_check(i, index):
    string = ""
    tc=0x00
    hashcode = crc32(i)
    tc = hashcode & 0xff ^ index
    if not (tc <= 57 and tc >= 48):
      return
    string += str(tc - 48)
    hashcode = crctable] ^ (hashcode >>8)
    tc = hashcode & 0xff ^ index
    if not (tc <= 57 and tc >= 48):
      return
    string += str(tc - 48)
    hashcode = crctable] ^ (hashcode >> 8)
    tc = hashcode & 0xff ^ index
    if not (tc <= 57 and tc >= 48):
      return
    string += str(tc - 48)
    hashcode = crctable] ^ (hashcode >> 8)
    return


def getuid(string):
    create_table()
    index =
    i = 0
    ht = int(f"0x{string}", 16) ^ 0xffffffff
    for i in range(3,-1,-1):
      index = get_crc_index(ht >> (i*8))
      snum = crctable]
      ht ^= snum >> ((3-i)*8)
    for i in range(100000000):
      lastindex = crc32_last_index(i)
      if lastindex == index:
            deepCheckData = deep_check(i, index)
            if deepCheckData:
                break
    if i == 100000000:
      return -1
    return f"{i}{deepCheckData}"

六、hashuid转uid的exe成品
我根据Hatsune_miku前辈的python算法用C语言做出了exe,效率更快


七、改进版完整成品
上述所用方法单个视频最多只能获得1500条弹幕,要想获取完整弹幕及其发送者信息需要网页分析获得,我之前做过一个exe程序可以获得完整版弹幕(亲测上万条弹幕运行正常),有空发上来,敬请期待

厄斐琉斯 发表于 2020-7-31 23:27

本帖最后由 厄斐琉斯 于 2020-7-31 23:40 编辑

野松子♂ 发表于 2020-7-31 23:27
效率怎么样?我用易语言抄了个一样的,uid数值一大能算几分钟...
C语言大概1秒4-5个,python大概0.8-1秒1个

马可solo 发表于 2020-8-2 14:41

https://comment.bilibili.com/' + cid + '.xml这个只能获取3000条,怎么获取指定时间段的全弹幕我还在研究

heju 发表于 2020-7-31 23:25

这个比较牛了。

greatslime 发表于 2020-7-31 23:39

正好旅游回来,过来看到想要的,感谢分享

2smart 发表于 2020-7-31 23:59

太厉害了,新人进来看一眼

麻辣隔壁 发表于 2020-8-1 00:09

好评好评,顶你。

有名字的过客 发表于 2020-8-1 00:27

这就厉害了啊

飞龙project 发表于 2020-8-1 00:57

请问能不能给个GitHub链接,正好star一下

ilnt 发表于 2020-8-1 01:02

弹幕演员暴露,哈哈哈

Dannyfox123 发表于 2020-8-1 01:36

Thank you for share
页: [1] 2 3
查看完整版本: 【原理讲解附源码】找到B站弹幕的发送者