利用Python脚本逆向解析Bilibili弹幕发送者UID
本文详细解析如何通过Python脚本获取Bilibili视频弹幕数据,并逆向分析其中的用户UID加密机制。文章介绍了获取弹幕CID的两种接口方式,重点阐述了利用CRC32算法生成的16进制校验码,通过构建无符号整型彩虹表来反查用户UID的技术方案,并结合Python与PHP实现了完整的查询工具。
Bilibili弹幕发送者查询原理概述
众所周知,Bilibili平台并未提供直接查看弹幕发送者身份的功能。这导致当用户看到令人不适的弹幕时,虽感愤怒却无从追究。然而,B站支持屏蔽特定用户发送的弹幕,这暗示其数据接口中必然包含用户身份信息。鉴于近期正在研究爬虫技术,我决定首先定位弹幕相关的数据接口,并深入分析其数据结构。
弹幕数据接口定位与获取
接口定位
定位接口的方法通常是打开任意视频页面并按下F12开发者工具。但在尝试搜索两圈后,我并未找到直接暴露弹幕发送者信息的接口。既然无法通过常规手段获取,便转向搜索引擎查找已知方案。果然,找到了两个返回XML格式数据的接口。
https://comment.bilibili.com/+cid https://api.bilibili.com/x/v1/dm/list.so?oid=+cid
上述接口中的cid是视频独有的数字标识,每一集视频对应一个唯一的cid。获取cid的方法是在视频页面按F12打开开发者工具,使用Ctrl+F搜索“cid”关键词,通常八九位数的数字即为所求的cid。
此外,我还发现了一个通过aid(视频作品ID)获取cid的接口。
https://www.bilibili.com/widget/getPageList?aid=+aid
弹幕数据结构分析与UID加密机制
数据分析
既然成功获取了弹幕数据,接下来需要解析这些数据的具体含义和用途。

CRC32校验码与数据库存储策略
通过对数据结构进行分析,可以提取出两个关键信息:第6个字段为时间戳,第8个字段则是用户UID经过某种加密处理后的结果。经查询确认,该字段是用户UID经过CRC32校验后转换成的16进制数。这意味着只能由UID生成校验码,而无法直接反向推导出UID。这似乎暗示需要通过彩虹表的方式进行数据查找。那么,在数据库中存储这串8位16进制数字应采用何种类型? 选项包括varchar和bigint。考虑到B站拥有约6亿用户,在6亿条数据中查找特定字符串的速度必然较慢(尽管有测试表明varchar与bigint的查找速度差异并不显著)。 在我决定使用bigint存储数据时,突然意识到8位16进制数对应的是2的32次方。有符号int类型的上限是2的31次方,但如果使用无符号整型(unsigned int)存储,其上限正好是2的32次方,即能容纳到0xffffffff这么大的数据,完全满足存储需求。因此,我果断改用无符号int类型,并将id也设为无符号int,以crc32b编码后的数据作为主键,构建彩虹表并存储至服务器。 (粗略估算,6亿条数据大约需要27G的存储空间……而我的服务器总容量仅为40G……)
Python与PHP全栈实现方案
Web应用开发
后续的操作逻辑相对顺畅。我编写了一个Python脚本,该脚本接收两个参数:视频cid和待搜索的弹幕关键字,返回结果包括发送弹幕的用户、该用户的crc32b编码值以及时间戳。随后,利用PHP的exec函数执行Python代码,并通过搜索本地数据库找出对应的用户UID,最后由PHP返回JSON格式的数据供前端展示。
Python代码实现(代码质量一般)
import requests
from bs4 import BeautifulSoup
import re
import io
import sys
sys.stdout = io.TextIOWrapper(sys.stdout.buffer,encoding='utf-8')
req = requests.get('https://comment.bilibili.com/'+sys.argv[1]+'.xml')
req.encoding = req.apparent_encoding
soup = BeautifulSoup(req.text, 'html.parser').find_all(name='d')
result = ""
for i in soup:
s = re.sub('<(.*?)>', '', str(i))
index = 0
if(len(sys.argv[2])>0):
index = s.find(str(sys.argv[2]))
if(index!=-1):
result+=str(i).split(",")[6]+","+s+","+str(i).split(",")[4]+","
print(result)
效果演示
前端代码为简易实现,主要目的是验证功能可行性。


此处显示为NULL的原因在于,我的服务器仍在缓慢地将彩虹表数据写入数据库,预计需要4天时间完成写入。 今日新增了一个暴力破解功能,以避免查询结果为NULL,但代价是查询速度会显著降低。
最后,附上该工具的使用链接:点我
总结与工具分享
总结
至此,关于利用Python脚本查找Bilibili弹幕发送者的介绍结束。更多关于Bilibili弹幕发送者的内容,请搜索本站历史文章或继续浏览相关文章,希望大家今后多多支持本站!
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













