B站弹幕姬(🐔)分析与开发(上篇)
辞职之后 休息了一段时间,最近准备开始恢复去工作的状态了,所以搞点事情来练练手。由于沉迷b站女妆大佬想做个收集弹幕的然后根据弹幕自动回复一些弹幕的东西。网上搜了一下有个c#的版本,感觉还做得不错,于是准备自己也搞一个,顺便分析一下b站家的协议。
收集需要的信息:
我首先使用charles或者如果你是windows平台的话使用findder抓下http包。看下是否弹幕信息使用的是http api来进行传输的。抓了半天,我并没有发现任何关于弹幕的信息,就可以判定没有走http。其实仔细想下,弹幕是有可能非常大量的,例如某个房间刷了一个小电视。整个屏幕都飘着bilibili干杯。。如果是http协议进行拉取的话我估计后台服务器是遭不住。但是抓取http包依然是有意义的,有一些api肯定会回传房间的信息,不然没有办法进行下面的工作。后面抓到的包也的确证实了我这个猜测。
来看下一个被捕捉到的有用的包里面的内容是什么:
https://api.live.bilibili.com
request:
GET /api/player?id=cid:&ts=15f2f17b037 HTTP/1.1 response:
<uid></uid> # 用户uid只有登陆之后的用户才会返回这个,没有登陆的用户不会
<uname></uname> # 用户昵称,同上
<login></login> # 登陆状态
<isadmin></isadmin> # 是否管理员
<time></time> # 时间戳
<rank></rank> # 排名
<level></level> # 等级
<state>LIVE</state> # 这个应该是直播间状态
<chatid></chatid> # 交谈id 这个不太清楚做什么用
<server>livecmt-.bilibili.com</server> # 服务器地址(特别注意的时这个服务器也可以接收到弹幕推送。应该是它们网站历史遗留的现在dm服务器有专门的地址返回了)
<sheid_user></sheid_user> # sheid这个不知道是啥
<block_time></block_time> # 这个应该是被封的时间
<block_type></block_type> # 被封禁的类型
<room_shield></room_shield> # 房间的sheid
<level_sheid></level_sheid> # sheid的level
<user_sheid_keyword></user_sheid_keyword> # 不知道。。
<room_silent_type></room_silent_type> # 这个应该是房间禁言类型
<room_silent_level></room_silent_level> # 禁言类型
<room_silent_second></room_silent_second> # 禁言秒数
<user_silent_level></user_silent_level> # 用户禁言等级
<user_silent_rank></user_silent_rank> # 用户禁言排名
<user_silent_verify></user_silent_verify> # 用户禁言确认
<dm_ws_port></dm_ws_port> # (重头戏)弹幕服务器端口号
<dm_wss_port></dm_wss_port> # 弹幕服务器端口号2
<dm_port></dm_port> # 弹幕服务器端口号3
<dm_server>broadcastlv.chat.bilibili.com</dm_server> # 弹幕服务器地址
<need_authority></need_authority> # 是否需要认证
<authority_range>日本</authority_range> # 授权区域(这个应该是本机ip地址的地区)
<forbidden></forbidden>
这是一个请求player详情的api,方便理解我都标注了每个字段大概是什么意思。(我也是根据对比猜测。因为这不是开放api)
可以看到其实跟我们需要的弹幕相关的只有几项,一个是弹幕服务器地址<dm_server> 还有就是dm_port 弹幕端口。弹幕端口最近新家了<dm_ws_port>我估计这个按字面意思来理解应该是html5 live 播放器可以直接使用websocket和服务器握手,然后接受弹幕推送。没有测试过,这一部分不做深度讨论了。
另外需要注意的一个api是:
https://api.live.bilibili.com/room/v1/Room/getRoomInfoMain?roomid=74723
这个是得到房间信息的api,可以得到用户信息的api对比看看,发现它们的api设计真的有点分裂,感觉应该不是同一时期设计的api。
response:
{
"code": ,
"msg": "ok",
"message": "ok",
"data": {
"MASTERID": ,
"ANCHOR_NICK_NAME": "万四屋",
"ROOMID": ,
"_status": "on",
"LIVE_STATUS": "LIVE",
"ROUND_STATUS": "",
"AREAID": "",
"BACKGROUND_ID": ,
"ROOMTITLE": "技术型萝莉吃鸡(。・ω・。)自走移动盒",
"COVER": "https://i0.hdslb.com/bfs/live/74723.jpg?10191128",
"LIVE_TIMELINE":
}
}
这里可以看到一个room_id。这个room_id其实蛮重要的,因为最开始我在对很多房间进行访问的时候发现几乎所有有人气的主播都是用的短房间码,但是这个三位数的短房间码并不能作为传输数据使用,所以真正的房间好吗是这里的room_id,我们后面在和服务器进行通信的时候会使用到这个。
既然http只能获取到这些信息,那么我们使用wireshark来进一步查看当直播间打开之后发生了什么,以便作更详细的分析。在osx平台下面第一次使用wireshark使用wifi抓包可能会被提示权限不足等说法
You don't have permission to capture on that device
使用sudo chmod 777 /dev/bpf*开放设备权限给wireshark使用就可以监听到数据包了。
如果我们需要知道数据包发送和抓取相关包我们可能需要在wireshark里面过滤出来自己需要的数据。那么我们可以基于ip地址来过滤获取数据。那么我们怎么知道该过滤哪个地址?其实蛮简单的,我尝试了一下用上面api返回的弹幕服务器地址,然后直接就ping出了地址183.240.17.138 常用弹幕地址还有另外一个ip地址 223.99.231.13
piperck➜ /dev ᐅ ping broadcastlv.chat.bilibili.com
PING broadcastlv.chat.bilibili.com (183.240.17.138): data bytes
bytes from 183.240.17.138: icmp_seq= ttl= time=49.544 ms
--- broadcastlv.chat.bilibili.com ping statistics ---
packets transmitted, packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 49.544/49.544/49.544/0.000 ms
拿到地址之后使用wireshark过滤出我们需要的包。下面让我们来看数据:
前面三个包就是正常的tcp三次握手包。length为66字节的包是有填充tcp option选项的包,54字节是标准只包含头的包。
我们来看第一个从本地发送到弹幕服务器的包里面有些什么内容。忽略前面的包头我们从数据开始看:
00 00 00 37 这里我们可以看到数据包的length是55bytes 这里37hex应该对应十进制的正好是55,我们可以猜测这里放数据大小,可以多查看几个其他包来证明这个推断。
00 10这个我没有看出来是啥。。大概是个 magic_number吧,先放着。
00 01 这个应该是版本号。
00 00 00 07 这个是进入房间的数据。单从这个包里面是看不出来这个意思的,要比较更多通讯包和其他包可以推断。我先把结论放在这里。
00 00 00 01 这个是包类型。像这里就代表的一个数据认证 传输通讯类似这个意思的包,说明还在跟服务器交换信息,并不是一个正常的弹幕包之类的。与之相关的还有后面的心跳包。
除开前面这16字节用于交换数据(应该算是它们自己的协议了,用前面这16个字节交换一些需要的信息和数据)剩下的都是数据。我们需要模仿这个格式发送数据给b站的弹幕服务器告诉它们我们要去的房间号,uid这个参数如果是匿名登录的话是不会有固定数值的是一个随机数。因为我们弄弹幕机并不需要锁定上我们的账号的uid,所以这里可以就传随机数就行。
例如:
self._uid = u_id or int(100000000000000.0 + 200000000000000.0 * random.random())
在介绍下面数据传输相关的东西之前我必须说明一下。上面一定要正确握手,下面才能得到正常的数据。另外如果是抓取的网页的,时间在2017年10月之后貌似它们又更新了,在传输的时候加上了ssl 现在已经抓不到我上面说的那些包了。我只看到一些什么赛门铁克coperation,估计是加入了证书之类的东西。但是为了向下兼容上面说的方法依然可以获取弹幕和相关的数据。另外要说的是,b站的app传输的数据和网站的也略微不一样。如果是抓取的app的包,可以直接看到utf-8编码的数据,而且可以直接解,但是以前网站上的似乎还进行了gzip,抓包的时候看到的数据也不是能直接utf-8解码的数据要稍微麻烦一点。 这点我也是踩了坑,当时拿到无法看懂的数据也是一脸懵逼没有想到还被压缩了一次。
我将在下篇里面介绍弹幕传输的数据意义,以及心跳相关的东西。
相关代码我已经放在了github上面:
https://github.com/piperck/b_danmu_chicken/tree/master
B站弹幕姬(🐔)分析与开发(上篇)的更多相关文章
- B站弹幕姬(🐔)分析与开发(下篇)
接上篇 下面开始分析弹幕信息: 当我们在完成和服务器的握手之后,b站的弹幕服务器就会开始不停的开始给我们推送相关房间的弹幕消息了.老规矩前面16个字节是这个包的相关信息,我们先来看下这条消息的前面16 ...
- b站弹幕的爬取以及词云的简单使用
一.B站弹幕的爬取 1.分析发现,其弹幕都是通过list.so?=cid这个文件加载出来的,所以我们找到这个文件的请求头的请求url, 2. 打开url就能看到所有的评论 3. 上代码,解析 #!/u ...
- B站弹幕爬取 / jieba分词 - 全站第一的视频弹幕都在说什么?
前言 本次爬取的视频av号为75993929(11月21的b站榜首),讲的是关于动漫革命机,这是一部超魔幻现实主义动漫(滑稽),有兴趣的可以亲身去感受一下这部魔幻大作. 准备工作 B站弹幕的爬取的接口 ...
- Python之路,Day22 - 网站用户访问质量分析监测分析项目开发
Python之路,Day22 - 网站用户访问质量分析监测分析项目开发 做此项目前请先阅读 http://3060674.blog.51cto.com/3050674/1439129 项目实战之 ...
- Java爬取B站弹幕 —— Python云图Wordcloud生成弹幕词云
一 . Java爬取B站弹幕 弹幕的存储位置 如何通过B站视频AV号找到弹幕对应的xml文件号 首先爬取视频网页,将对应视频网页源码获得 就可以找到该视频的av号aid=8678034 还有弹幕序号, ...
- 萌新学习Python爬取B站弹幕+R语言分词demo说明
代码地址如下:http://www.demodashi.com/demo/11578.html 一.写在前面 之前在简书首页看到了Python爬虫的介绍,于是就想着爬取B站弹幕并绘制词云,因此有了这样 ...
- Python网络爬虫实战(三)照片定位与B站弹幕
之前两篇已经说完了如何爬取网页以及如何解析其中的数据,那么今天我们就可以开始第一次实战了. 这篇实战包含两个内容. * 利用爬虫调用Api来解析照片的拍摄位置 * 利用爬虫爬取Bilibili视频中的 ...
- [原创]Android Monkey 在线日志分析工具开发
[原创]Android Monkey 在线日志分析工具开发 在移动App测试过程中,Monkey测试是我们发现潜在问题的一种非常有效手段,但是Android原生的Monkey有其天然的不足,数据不能有 ...
- B站弹幕爬取
B站弹幕爬取 单个视频弹幕的爬取 B站弹幕都是以xml文件的形式存在的,而xml文件的请求地址是如下形式: http://comment.bilibili.com/233182992.xml ...
随机推荐
- 解决VS Code使用code runner开发Python乱码问题
微软开发的VS Code是一个跨平台的文本编辑器,通过各种插件,可以把自己武装成无所不能的IDE. 刚刚安装完VS Code时,迫不急待地安装了C/C++.Python以及Code Runner插件, ...
- filter 实现登录状态控制
每天学习一点点 编程PDF电子书.视频教程免费下载:http://www.shitanlife.com/code 网站需要做用户登录鉴权控制,没有登录的话,不能访问网站,提示需要登录. 实现方式: 使 ...
- 【转】android SDK中的ddms使用详解
一.查看线程信息1.展开左侧设备节点,选择进程: 2.点击更新线程信息图标: 注意:如果你没有运行或调试程序的话,这些图标是不可用的! 3.右侧选择“Threads”标签: 二.查看堆栈信息1.展开左 ...
- WiFi-ESP8266入门http(2-2)文件系统-复杂结构的网页 + 文本框交互WIFI信息
网友教程:https://blog.csdn.net/solar_Lan/article/details/74231360 通过网友教程,我们搭建了文件系统.在此基础上,我们增加WIFI交互. 现有功 ...
- jenkins使用1----初始化设置
####一.基本设置 1.首先找到系统管理 2.再找到全局配置一把黄色的锁头 3.新增JDK.Maven等 别名随便 下面的值添加jdk在jenkins这台机器上的位置,如果没找到可以点击自动安装,并 ...
- Java关键字(四)——final
对于Java中的 final 关键字,我们首先可以从字面意思上去理解,百度翻译显示如下: 也就是说 final 英文意思表示是最后的,不可更改的.那么对应在 Java 中也是表达这样的意思,可以用 f ...
- 史上最全面的Docker容器引擎使用教程
目录 1.Docker安装 1.1 检查 1.2 安装 1.3 镜像加速 1.4 卸载Docker 2.实战Nginx 3.Docker命令小结 4.DockerFile创建镜像 4.1 Docker ...
- 【重磅】Spring Boot 2.1.0 权威发布
如果这两天登录 https://start.spring.io/ 就会发现,Spring Boot 默认版本已经升到了 2.1.0.这是因为 Spring Boot 刚刚发布了 2.1.0 版本,我们 ...
- .netcore 堆栈调用方法小记
背景 上午临近午饭时,公司同事反馈验证码被攻击灌水.我们匆忙查询验证码明细,对已频繁出现的IP插入黑名单,但IP仍然隔断时间频繁变动,不得已之下只能先封禁对应公司id的验证码发送功能.年初时候,专门对 ...
- 窥探ASP.Net MVC底层原理 实现跨越Session的分布式TempData
1.问题的引出 我相信大家在项目中都使用过TempData,TempData是一个字典集合,一般用于两个请求之间临时缓存数据或者页面之间传递消息.也都知道TempData是用Session来实现的,既 ...