转载自

https://ihomura.cn/2018/05/17/Bilibili%E7%9B%B4%E6%92%AD%E5%BC%B9%E5%B9%95%E6%8A%93%E5%8F%96-3-%E5%BC%B9%E5%B9%95%E4%BC%A0%E8%BE%93%E5%8D%8F%E8%AE%AE%E5%88%86%E6%9E%90/z

前言

有了前两篇的铺垫,其实到这里再去分析基本就没有什么难点了,无非是苦力活罢了。

所以这篇文章主要是总结如何更好的分(偷)析(懒)。

抓包分析

弹幕消息

这里挑选了一个比较典型的包,它包括了弹幕内容并且有多条弹幕。

可以很明显看出,它是由两条弹幕构成的:

其中选中的文本部分显然是一个JSON,前面的非 ASCII 码没猜错应该就是头部了,我们看一下第一条弹幕的头部。

1
00 00 01 0F 00 10 00 00 00 00 00 05 00 00 00 00

首先头部的长度是 16,也就是 0x10,所以大胆猜测其中的 00 10 字段就是头部长度,结合后面第二条弹幕头部的相同字段的值,基本确定就是头部长度。

那么可以猜测前面 00 00 01 0F 也就是 0x10F (别忘了 TCP 是大端序),应该是这条弹幕帧(头部+JSON文本数据)的长度。

观察到偏移 0X10F 处开始正好是第二条弹幕的内容,而且第二条弹幕头部中这个字段的值是 0x125,两者相加是 0x234 即整个包的长度,所以确定猜测是正确的。

此外还有一个非零值是 0x5,暂时猜测不出来它的意思,先放放。

也就是说目前头部分析出来的结果是:

1
2
| 00 00 01 0F | 00 10 | 00 00 00 00 00 05 00 00 00 00
| 帧长度 | 头部长度 | 未知 |

然后我们再把注意力放到后面的 JSON 数据上,这里切换到 Fiddler 的 JSON 视图:

由于头部部分不是 UTF-8 编码干扰了解码,所以 Fiddler 只解析出来了第一条弹幕的文本部分,不过已经足够了。

其中有一个很重要的字段是 cmd,显然是 command 的缩写,它的值是 DANMU_MSG,所以显然是“弹幕消息”的意思。实际上通过抓包还可以看到有 WISH_BOTTLE, SEND_GIFT 等值,因此可以确定 cmd 用来指明弹幕的种类。

同时可以看到 info 中直接就包含了弹幕的内容(“看不懂”)、弹幕发送者的 id (“266649406”)、弹幕发送者的昵称(“简短回忆”)和头衔(“靖菌”)等等内容。

到这里弹幕的内容我们就可以抓取到了,但是还有一些细节性的东西。

人气值

持续抓包一段时间后,我们可以看到有非常多这样长度固定并且一来一回的包。

分别查看内容如下:

可以看到上行包长度固定是 16,下行包固定长度是 20,它们头部字段的含义跟之前的分析吻合,同时在下行的包中可以发现其中四字节的字段 0x73E8 就是人气值。

另外刚才弹幕包中头部为 0x5 的字段这里变成了 0x2 和 0x3,因此猜测应该是消息种类。

这里头部最后一个字段出现了一个 0x1,暂时不知道什么意思,先放着。

握手

现在我们回过头来分析最开始的握手包。

首先是请求包。

可以看到跟之前的分析都是吻合的,而且这里消息种类是 0x7 代表客户端请求连接,同时后面的文本信息包含了用户 id(这里我是游客,所以是0)、房间 id、客户端类型和客户端版本等信息。

然后是返回的包。

这个包很简单,只要头部,并且其中消息种类 0x8 表示服务器接受连接。

总结

可以看出,抓取弹幕的核心是要正确解析头部中的消息种类,目前出现过的种类有:

  • 0x2 客户端请求人气值
  • 0x3 服务端返回人气值
  • 0x5 弹幕消息、礼物等等
  • 0x7 客户端请求连接
  • 0x8 服务端允许连接

以及头部的结构:

1
| 帧长度(4) | 头部长度(2) | 未知1(2) | 消息种类(4) | 未知(4) |

虽然还有很多未知的字段,不过按照目前掌握的内容已经足以正常抓取弹幕了。

站在巨人的肩膀上

decorator.js

抓包总是有限制的,当然我们也可以选择分析前端的代码,不过我当时看到 .min 就放弃了:

不过 Chrome 格式化之后搜索 DANMU_MSG 后还是有点收获的:

可以看到之前 cmd 的其它取值。

但是分析这个文件是真的难受,我看了 30min 就放弃了,不知道有没有好的分析办法。

Bilibili HTML5 Live

后来我偶然发现了这个脚本:Bilibili HTML5 Live

它包含了之前我抓包分析的内容,还有一些我没有分析到的内容,总之看这份代码基本上就可以偷懒了(逃

比如之前提到的消息种类判定代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
function onMessage(evt) {    var data = evt.data;
    var dataView = new DataView(data, 0);
    var packetLen = dataView.getUint32(packetOffset);
    if (dataView.byteLength >= packetLen) {        var headerLen = dataView.getInt16(headerOffset);
        var ver = dataView.getInt16(verOffset);
        var op = dataView.getUint32(opOffset);
        var seq = dataView.getUint32(seqOffset);
        switch (op) {            case 8:
                this.heartBeat();
                heartbeatInterval = setInterval(this.heartBeat.bind(this), 30 * 1000);
                break;
            case 3:
                if (this._listener) this._listener('online', dataView.getInt32(16));
                break;
            case 5:
                var packetView = dataView;
                var msg = data;
                var msgBody;
                for (var offset = 0; offset < msg.byteLength; offset += packetLen) {                    packetLen = packetView.getUint32(offset);
                    headerLen = packetView.getInt16(offset + headerOffset);
                    msgBody = textDecoder.decode(msg.slice(offset + headerLen, offset + packetLen));
                    if (!msgBody) {                        textDecoder = getDecoder(false);
                        msgBody = textDecoder.decode(msg.slice(offset + headerLen, offset + packetLen));
                    }
                    if (this._listener) this._listener('msg', msgBody);
                }
                break;
        }
    }
}

此外可以看到之前的“未知1”字段是版本号,“未知2”字段可能是序列编号?这里存疑,不过不影响抓取弹幕。

小结

Bilibili 弹幕抓取系列到这里就结束了,这个过程中虽然绕了很多弯路浪费了大把时间,不过我还是学到了不少知识:

  • WebSocket
  • FiddlerScript 编写
  • WireShark 基本使用
  • 抓包分析能力(二进制敏感度?)

另外感觉计网光过了一遍课本真的不够,用起来总是觉得力不从心,等什么时候闲下来就去做计网实验吧(挖坑)。

Bilibili直播弹幕抓取(3):弹幕传输协议分析相关推荐

  1. Bilibili直播弹幕抓取(1):WebSocket

    Bilibili直播弹幕抓取(1):WebSocket 转载自https://ihomura.cn/2018/05/14/Bilibili%E7%9B%B4%E6%92%AD%E5%BC%B9%E5% ...

  2. python爬虫----简单的抓取斗鱼弹幕

    近几年来直播越来越火,看直播也成为了人们生活的娱乐项目 个人也是比较喜欢看直播,看着主播的搞笑的操作和弹幕不时会开怀大笑. 于是就想能不能把弹幕抓取下来,带着这个问题我就点开了一个直播间.按照以前学过 ...

  3. 抖音弹幕抓取(适合纯小白)

    抖音弹幕抓取 准备代码 准备环境 运行 算是一个使用记录,代码和具体的环境配置已经有前辈写的很棒了,只是把这些整合到了一起,防止遗忘,也希望帮助到有需要的人. 准备代码 在github下载代码并解压, ...

  4. “免费午餐”成为销量第一,看明星吉杰淘宝直播如何抓取粉丝眼球

    29日晚,明星吉杰淘宝直播[第九届"穷人"狂欢节],6个多小时的直播里,吉杰共上架70件商品,1条免费午餐公益捐助链接.获得超过300万观看,带货销量近45万,销售额(估)达160 ...

  5. 斗鱼直播地址抓取——转载

    先附上原地址斗鱼直播真实地址解析,直播源抓取方法 找了很久发现52pj上有一个帖子把自己尝试出来的办法发出来了,虽然有点分功夫,但还是发现了规律,难得的毅力.以下为摘录: 2019-5-19重磅更新: ...

  6. python抓取直播源 并更新_电视直播源抓取工具箱

    很多时候你们在pc端看电视直播,都会出现直播源失效的情况,这样就可以用到电视直播源抓取工具箱,帮助你们自动抓取最新的直播源,让你们能够随时的观看自己喜欢的电视内容. 软件简介: 经常看到大家电视直播源 ...

  7. Java版 QQ空间自动登录无需拷贝cookie一天抓取30WQQ说说数据流程分析【转】

    Java版 QQ空间自动登录无需拷贝cookie一天抓取30WQQ说说数据&流程分析 QQ空间说说抓取难度比较大,花了一个星期才研究清楚! 代码请移步到GitHub GitHub地址:http ...

  8. 如何在php搜索显示数据库数据结构_PHP如何实现抓取百度搜索结果并分析数据结构...

    PHP如何实现抓取百度搜索结果并分析数据结构 发布时间:2020-09-26 09:26:19 来源:亿速云 阅读:95 作者:小新 这篇文章主要介绍PHP如何实现抓取百度搜索结果并分析数据结构,文中 ...

  9. 使用Chrome快速实现数据的抓取(二)——协议 - 天方 - 博客园

    使用Chrome快速实现数据的抓取(二)--协议 - 天方 - 博客园

最新文章

  1. Xilinx Altera FPGA中的逻辑资源(Slices VS LE)比较
  2. vba和python哪个好学-python和vba学哪个
  3. python输入语句-Python中的模块导入和读取键盘输入的方法
  4. python写gui导入图片并处理_Python图像处理库:Pillow 初级教程
  5. 开始---《C++ primer》随笔
  6. PIE SDK剔除栅格块算法
  7. [记录] ---阿里云java.io.IOException: Connection reset by peer的问题
  8. java 数组map_Java之数组array和集合list、set、map
  9. mount.nfs: Stale file handle的解决方法
  10. apache POI技术的使用
  11. Fade To Black《消失在黑暗中》BY Metallica [转]
  12. 电脑上没有tts信息服务器,TTS——让你的电脑会说话-win7 tts
  13. c++ iostream
  14. Windows Server2008下安装JDK
  15. oracle中分号和双引号用法,深入理解oracle中单引号与双引号的用法区别
  16. 夏雨老师告诉您学习平面设计到底好不好呢?
  17. NB-IoT、LoRa、sigfox低功耗广域物联网技术,未来的争夺之战
  18. intellij idea 创建web 项目
  19. 10个最好用的在线配色网站推荐
  20. vue实现消息badge 标记_Badge 标记

热门文章

  1. PHP获取一个网页内的图片_分享创造-使用PHP开发一键获取网页所有图片
  2. 小米电视注册显示访问服务器失败,为什么手机看电视连接上却出现服务器连接异常 – 手机爱问...
  3. 牛刀:姚景源的悲哀和中国民生的艰难
  4. iPhone手机关掉这3个设置,不仅省电,而且手机还不会出现卡顿
  5. Trafodion CQD-comp_bool_158
  6. 多少分才能考上重庆计算机学校,考多少分才能上重庆大学 录取分数是多少
  7. Sql-server数据库搭建
  8. ios颜色设置的三种方式
  9. MYSQL学习与数据库综合实验(八)——存储过程实验
  10. Mybatis的RowBounds分页