【Python3爬虫】斗鱼弹幕爬虫
在网上找到了一份斗鱼弹幕服务器第三方接入协议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爬虫】斗鱼弹幕爬虫的更多相关文章
- 【收藏】收集的各种Python爬虫、暗网爬虫、豆瓣爬虫、抖音爬虫 Github1万+星
收集的各种Python爬虫.暗网爬虫.豆瓣爬虫 Github 1万+星 磁力搜索网站2020/01/07更新 https://www.cnblogs.com/cilisousuo/p/1209954 ...
- 放养的小爬虫--京东定向爬虫(AJAX获取价格数据)
放养的小爬虫--京东定向爬虫(AJAX获取价格数据) 笔者声明:只用于学习交流,不用于其他途径.源代码已上传github.githu地址:https://github.com/Erma-Wang/Sp ...
- 【Python网络爬虫一】爬虫原理和URL基本构成
1.爬虫定义 网络爬虫,即Web Spider,是一个很形象的名字.把互联网比喻成一个蜘蛛网,那么Spider就是在网上爬来爬去的蜘蛛.网络蜘蛛是通过网页的链接地址来寻找网页的.从网站某一个页面(通常 ...
- crawler_爬虫_反爬虫策略
关于反爬虫和恶意攻击的一些策略和思路 有时网站经常受到恶意spider攻击,疯狂抓取网站内容,对网站性能有较大影响. 下面我说说一些反恶意spider和spam的策略和思路. 1. 通过日志分析来 ...
- Python爬虫从入门到放弃(二十二)之 爬虫与反爬虫大战
爬虫与发爬虫的厮杀,一方为了拿到数据,一方为了防止爬虫拿到数据,谁是最后的赢家? 重新理解爬虫中的一些概念 爬虫:自动获取网站数据的程序反爬虫:使用技术手段防止爬虫程序爬取数据误伤:反爬虫技术将普通用 ...
- python爬虫(一)_爬虫原理和数据抓取
本篇将开始介绍Python原理,更多内容请参考:Python学习指南 为什么要做爬虫 著名的革命家.思想家.政治家.战略家.社会改革的主要领导人物马云曾经在2015年提到由IT转到DT,何谓DT,DT ...
- Python爬虫-01:爬虫的概念及分类
目录 # 1. 为什么要爬虫? 2. 什么是爬虫? 3. 爬虫如何抓取网页数据? # 4. Python爬虫的优势? 5. 学习路线 6. 爬虫的分类 6.1 通用爬虫: 6.2 聚焦爬虫: # 1. ...
- python爬虫之反爬虫(随机user-agent,获取代理ip,检测代理ip可用性)
python爬虫之反爬虫(随机user-agent,获取代理ip,检测代理ip可用性) 目录 随机User-Agent 获取代理ip 检测代理ip可用性 随机User-Agent fake_usera ...
- Python爬虫入门教程 65-100 爬虫与反爬虫的修罗场,点评网站,字体反爬之三
爬虫与反爬虫的修罗场 哪种平台最吸引爬虫爱好者,当然是社区类的,那里容易产生原生态,高质量的数据啊, 你看微博,知乎,豆瓣爬的不亦乐乎. 评论也是产生内容的好地方 生活类点评网站 旅游类点评网站 音乐 ...
随机推荐
- RabbitMQ Network Partitions的预警和处理策略
网络分区的意义 RabbitMQ的模型类似交换机模型,且采用erlang这种电信网络方面的专用语言实现.RabbitMQ集群是不能跨LAN部署(如果要WAN部署需要采用专门的插件)的,也就是基于网络情 ...
- bzoj 4008 亚瑟王 期望概率dp
对于这种看起来就比较傻逼麻烦的题,最关键的就是想怎么巧妙的设置状态数组,使转移尽可能的简洁. 一开始我想的是f[i][j]表示到第j轮第i张牌还没有被选的概率,后来发现转移起来特别坑爹,还会有重的或漏 ...
- myeclipse maven tomcat插件 创建web工程
自从有了云笔记,很久不写博客了.今天写了使用Freemarker静态化JSP页面,索性就发出来.初学,勿喷. 这篇文字以前放在云笔记里,当然里面有很多借鉴网络上的东西,而自己也使用Maven很久了,索 ...
- 关于String类型中==和equals的区别。
"=="操作符的作用 1.用于基本数据类型的比较,比较的是值. 2.用于比较对象,判断对象的引用是否指向堆内存的同一块地址. equals的作用 用于比较两个对象的内容是否相同 代 ...
- SpringBoot(三)_controller的使用
针对controller 中 如何使用注解进行解析 @RestController 返回数据类型为 Json 字符串,特别适合我们给其他系统提供接口时使用. @RequestMapping (1) 不 ...
- c#Socket服务器与客户端的开发(1)
上个项目中用到了Socket通讯,项目中直接借助SuperSocket实现,但是我觉得这毕竟是一个我没接触过的东西,所以也顺便学习了一下原生socket的使用,做了一个socket服务器与客户端的开发 ...
- Spring boot 继承 阿里 autoconfig 配置环境参数
前提:基于springboot 项目 1. 配置pom.xml 文件 <plugin> <groupId>com.alibaba.citrus.tool</groupId ...
- .Net Core使用Redis(CSRedis)
前言 CSRedis是国外大牛写的.git地址:https://github.com/2881099/csredis,让我们看看如果最简单的 使用一下CSRedis吧. 引入NuGet 获取Nuget ...
- 「拥抱开源, 又见 .NET」系列第三次线下活动简报
「拥抱开源, 又见 .NET」 随着 .NET Core的发布和开源,.NET又重新回到人们的视野. 自2016年 .NET Core 1.0 发布以来,其强大的生命力让越来越多技术爱好者对她的未来满 ...
- 立即执行函数 IIFE
立即执行函数表达式IIFE(Immediately-invoked function expression)我们知道,在javascript(ES5)中,是没有块级作用域的概念的.看一个例子 for ...