在网上找到了一份斗鱼弹幕服务器第三方接入协议v1.6.2,有了第三方接口,做起来就容易多了。

一、协议分析

斗鱼后台协议头设计如下:

这里的消息长度是我们发送的数据部分的长度和头部的长度之和,两个消息长度是一样。然后要注意的是该协议使用的是小端整数,所以我们要对数据进行处理后再发送,这里可以使用int.to_bytes()将整数转变成小端整数的形式。示例如下:

int.to_bytes(12,4,'little')   # b'\x0c\x00\x00\x00'

int.to_bytes(12,4,'big')     # b'\x00\x00\x00\x0c'

然后消息类型是689(689表示客户端发送给服务器,690表示服务器发送给客户端),加密字段和保留字段都是默认为0。这里由于消息类型是两个字节的,加密字段和保留字段都是一个字节,但是因为加密字段和保留字段都是0,所以这四个字节可以使用int.to_bytes(689,4,'little')来表示。最后该协议使用的是utf-8编码,所以我们需要对整个数据进行编码后再发送。

二、具体步骤

1、连接服务器

第三方客户端通过 TCP 协议连接到弹幕服务器(依据指定的 IP 和端口),其中IP 地址为openbarrage.douyutv.com,端口为8601,相关代码如下:

client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
host = socket.gethostbyname("openbarrage.douyutv.com")
port = 8601
client.connect((host, port))

2、发送登录请求

客户端向弹幕服务器发送登录请求,登录弹幕服务器,格式如下:

type@=loginreq/roomid@=房间号/

3、发送加组请求

客户端收到登录成功消息后发送进入弹幕分组请求给弹幕服务器,格式如下:

type@=joingroup/rid@=房间号/gid@=-9999/

gid表示分组号,第三方平台建议选择-9999即海量弹幕模式。

4、接收广播消息

接收服务器发送的广播消息,包括用户发的弹幕和送的礼物信息,然后解析得到具体的内容。但这些数据里只有礼物的id而没有具体的礼物名称,然后我通过抓包找到了两个链接,里面包含了礼物id和名称的对应关系,相关代码如下:

 gift_dict = {}
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.75 Safari/537.36"
}
url1 = "https://webconf.douyucdn.cn/resource/common/gift/flash/gift_effect.json"
res1 = requests.get(url1, headers=headers)
js1 = json.loads(res1.text.lstrip('DYConfigCallback(').rstrip(');'))
gift_data1 = js1['data']['flashConfig']
9 for i in gift_data1.keys():
gift_dict[gift_data1[i]['id']] = gift_data1[i]['name'] url2 = "https://webconf.douyucdn.cn/resource/common/prop_gift_list/prop_gift_config.json"
res2 = requests.get(url2, headers=headers)
js2 = json.loads(res2.text.lstrip('DYConfigCallback(').rstrip(');'))
gift_data2 = js2['data']
for i in gift_data2.keys():
gift_dict[int(i)] = gift_data2[i]['name']

5、发送心跳消息

客户端每隔45秒给服务器发送一次心跳消息,用于维护和服务器后台间的联系,格式如下:

keep_msg = "type@=keeplive/tick@=十位时间戳"  # 旧版心跳消息
keep_msg = "mrkl/" # 新版心跳消息

6、核心代码

在发送数据的时候,有可能会出现一次无法发送完的情况,所以就需要多发送几次,确保把数据都发送出去:

 msg = msg + '\0'  # 数据以'\0'结尾
msg = msg.encode('utf-8') # 使用utf-8编码
length = len(msg) + 8 # 消息长度
code = 689 # 消息类型
# 消息头部:消息长度+消息长度+消息类型+加密字段(默认为0)+保留字段(默认为0)
head = int.to_bytes(length, 4, 'little') + int.to_bytes(length, 4, 'little') + int.to_bytes(code, 4, 'little')
# 发送头部部分
client.send(head)
# 发送数据部分
sent = 0
while sent < len(msg):
n = client.send(msg[sent:]) # 返回已发送的数据长度
sent = sent + n

三、运行结果

运行截图:

进入数据库查看结果:

db.getCollection('DouYu-6039226').find({"data_type":"gift"})

结果如下:

还可以看看大家都发了什么弹幕:

db.getCollection('DouYu-6039226').find({"data_type":"chat"},{"user_name":1,"chat_txt":1,"_id":0})

结果如下:

完整代码已上传到GitHub

【Python3爬虫】斗鱼弹幕爬虫的更多相关文章

  1. 【收藏】收集的各种Python爬虫、暗网爬虫、豆瓣爬虫、抖音爬虫 Github1万+星

    收集的各种Python爬虫.暗网爬虫.豆瓣爬虫  Github 1万+星 磁力搜索网站2020/01/07更新 https://www.cnblogs.com/cilisousuo/p/1209954 ...

  2. 放养的小爬虫--京东定向爬虫(AJAX获取价格数据)

    放养的小爬虫--京东定向爬虫(AJAX获取价格数据) 笔者声明:只用于学习交流,不用于其他途径.源代码已上传github.githu地址:https://github.com/Erma-Wang/Sp ...

  3. 【Python网络爬虫一】爬虫原理和URL基本构成

    1.爬虫定义 网络爬虫,即Web Spider,是一个很形象的名字.把互联网比喻成一个蜘蛛网,那么Spider就是在网上爬来爬去的蜘蛛.网络蜘蛛是通过网页的链接地址来寻找网页的.从网站某一个页面(通常 ...

  4. crawler_爬虫_反爬虫策略

    关于反爬虫和恶意攻击的一些策略和思路   有时网站经常受到恶意spider攻击,疯狂抓取网站内容,对网站性能有较大影响. 下面我说说一些反恶意spider和spam的策略和思路. 1. 通过日志分析来 ...

  5. Python爬虫从入门到放弃(二十二)之 爬虫与反爬虫大战

    爬虫与发爬虫的厮杀,一方为了拿到数据,一方为了防止爬虫拿到数据,谁是最后的赢家? 重新理解爬虫中的一些概念 爬虫:自动获取网站数据的程序反爬虫:使用技术手段防止爬虫程序爬取数据误伤:反爬虫技术将普通用 ...

  6. python爬虫(一)_爬虫原理和数据抓取

    本篇将开始介绍Python原理,更多内容请参考:Python学习指南 为什么要做爬虫 著名的革命家.思想家.政治家.战略家.社会改革的主要领导人物马云曾经在2015年提到由IT转到DT,何谓DT,DT ...

  7. Python爬虫-01:爬虫的概念及分类

    目录 # 1. 为什么要爬虫? 2. 什么是爬虫? 3. 爬虫如何抓取网页数据? # 4. Python爬虫的优势? 5. 学习路线 6. 爬虫的分类 6.1 通用爬虫: 6.2 聚焦爬虫: # 1. ...

  8. python爬虫之反爬虫(随机user-agent,获取代理ip,检测代理ip可用性)

    python爬虫之反爬虫(随机user-agent,获取代理ip,检测代理ip可用性) 目录 随机User-Agent 获取代理ip 检测代理ip可用性 随机User-Agent fake_usera ...

  9. Python爬虫入门教程 65-100 爬虫与反爬虫的修罗场,点评网站,字体反爬之三

    爬虫与反爬虫的修罗场 哪种平台最吸引爬虫爱好者,当然是社区类的,那里容易产生原生态,高质量的数据啊, 你看微博,知乎,豆瓣爬的不亦乐乎. 评论也是产生内容的好地方 生活类点评网站 旅游类点评网站 音乐 ...

随机推荐

  1. 在echarts里在geojson绘制的地图上展示散点图(气泡)、线集。

    先来要实现的效果图: 下方图1是官网的案例:http://www.echartsjs.com/gallery/editor.html?c=scatter-map 下图2是展示气泡类型为pin的效果: ...

  2. 在vs中编写代码常用的快捷键

    作为一个程序员,能够熟悉使用各种快捷键,可以增加我们编写和调试代码的速度,下面我就对常使用的快捷键做一些总结,下面这些快捷键基本适用于所有版本的vs: 最给力: Ctrl+K+F   快速整理代码格式 ...

  3. Java基础-方法重载和方法重写的区别

    什么是java方法重载 (1) 方法重载是让类以统一的方式处理不同类型数据的一种手段.多个同名函数同时存在,具有不同的参数个数/类型. 重载Overloading是一个类中多态性的一种表现. (2)  ...

  4. COGS2421 [HZOI 2016]简单的Treap

    题面见这里 大概是个模板题 Treap暴力插入的做法太暴力了并不优美 这里就需要用到笛卡尔树的构造方法,定义见这里 在 假的O(n) 的时间内构造一棵Treap 把元素从小到大排序 这样从小到大插入时 ...

  5. 带logo图片或不带logo图片的二维码生成与解析,亲测成功

    最近公司需要实现二维码功能,本人经过一顿百度,终于实现了,因有3个功能:不带logo图片.带logo图片.解析二维码,篇幅较长,请耐心读之,直接复制粘贴即可. 前提:myeclipse10:jar包: ...

  6. 【Python实践-6】将不规范的英文名字,变为首字母大写,其他小写的规范名字

    #利用map()函数,把用户输入的不规范的英文名字,变为首字母大写,其他小写的规范名字. def f1(s): s=s.capitalize() return s list1= ['adam', 'L ...

  7. .net core 程序退出事件

    平滑关闭,关闭事件 //捕获Ctrl+C事件 Console.CancelKeyPress += Console_CancelKeyPress; //进程退出事件 AppDomain.CurrentD ...

  8. Docker最全教程之使用Docker搭建Java开发环境(十七)

    前言 Java是一门面向对象的优秀编程语言,市场占有率极高,但是在容器化实践过程中,发现官方支持并不友好,同时与其他编程语言的基础镜像相比(具体见各语言镜像比较),确实是非常臃肿. 本篇仅作探索,希望 ...

  9. 第9章 设备授权端点(Device Authorization Endpoint) - IdentityModel 中文文档(v1.0.0)

    OAuth 2.0设备流设备授权的客户端库是作为HttpClient扩展方法提供的. 以下代码发送设备授权请求: var client = new HttpClient(); var response ...

  10. SpringBoot整合SpringCloud搭建分布式应用

    什么是SpringCloud? SpringCloud是一个分布式的整体解决方案.SpringCloud为开发者提供了在分布式系统中快速构建的工具,使用SpringCloud可以快速的启动服务或构建应 ...