近几年来直播越来越火,看直播也成为了人们生活的娱乐项目

个人也是比较喜欢看直播,看着主播的搞笑的操作和弹幕不时会开怀大笑。

于是就想能不能把弹幕抓取下来,带着这个问题我就点开了一个直播间。按照以前学过的方法好像根本没有办法弄到弹幕那一块,

于是赶紧去网上查,发现网上有不少人已经做了。呃......怎么说,大概了解了获取弹幕的原理,就是通过socket向斗鱼弹幕服务器发送请求,

然后服务器会返回数据给你,但是他们的具体操作不是太明白。没办法只好继续搜索,终于看到了一个知乎用户的专栏里的一篇文章,

@Ehco的   从零开始写Python爬虫 --- 爬虫应用: 利用斗鱼Api抓取弹幕  地址:https://zhuanlan.zhihu.com/p/28164017,

因为斗鱼现在已经开放了弹幕服务器接入协议,我也看了其他人也提到了这个,但具体怎么用这个协议还是不明白。

通过读了Ehco他的文章后才一点点的弄清楚。

因为之前完全不知道怎么弄,所以代码写的和原作者十分类似。

但我在注释中写了一些自己的理解,如果觉得不清楚可以去看原作者的文章。

也十分感谢原作者分享了这么好的文章。

好吧,下面就来说说我的理解

首先是斗鱼协议

《斗鱼弹幕服务器第三方接入协议v1.4.1》:

http://dev-bbs.douyutv.com/forum.php?mod=viewthread&tid=115&extra=page%3D1

《斗鱼第三方开放平台API文档v2.0》:

http://dev-bbs.douyutv.com/forum.php?mod=viewthread&tid=108&extra=page%3D1

这里我们只需要看第一个就行了

然后再看协议的内容

首先是协议头,这个最重要了,每个请求前面都要带这个

这部分的代码:

def send_request_msg(msgstr):msg = msgstr.encode('utf-8')#协议规定所有协议内容均为 UTF-8 编码data_lenth = len(msg) + 8#data_lenth表示整个协议头的长度(消息长度),包括数据部分和头部,len(msg)就是数据部分,8就是头部的长度code = 689#根据协议消息类型字段用689msghead = int.to_bytes(data_lenth,4,'little') + int.to_bytes(data_lenth,4,'little') + int.to_bytes(code,4,'little')#msghead是按照斗鱼第三方协议构造的协议头#前2段表示的是消息长度,最后一个是消息类型#这里还有个值得注意的一点,发送给服务器的类型和服务器返回的类型都是bytes,因此要把数据信息通过int.to_bytes()变成bytesclient.send(msghead)#发送协议头client.send(msg)#发送消息请求

接着就是获取弹幕的部分了

获取弹幕的步骤是这样的:

先要向服务器发送登录请求消息,再发送入组消息用于加入房间,

在获取弹幕的过程中还要发送心跳消息来维持和服务器的连接。

获取弹幕的代码:

def get_danmu(roomid):denglu_msg = 'type@=loginreq/roomid@={}/\0'.format(roomid)#登录请求消息,最后面的'\0',是协议规定在数据部分结尾必须是'\0'send_request_msg(denglu_msg)join_room_msg = 'type@=joingroup/rid@={}/gid@=-9999/\0'.format(roomid)#加入房间分组消息send_request_msg(join_room_msg)while True:data = client.recv(1024)#这个data就是服务器向客户端发送的消息#具体的信息可以看斗鱼弹幕第三方接入协议danmu_username = re.findall(user_id,data)dammu_content = re.findall(danmu,data)#print(data)if not data:breakelse:for i in range(0,len(danmu_username)):try:print('[{}]:{}'.format(danmu_username[i].decode('utf-8'),dammu_content[i].decode('utf-8')))#返回的数据是bytes型,所以要用decode方法来解码except:continuedef keeplive():#维持与后台的心跳#关于心跳消息,协议中有详细的解释while True:live_msg = 'type@=keeplive/tick@=' + str(int(time.time())) + '/\0'send_request_msg(live_msg)time.sleep(15)

主体部分大概就是这么多了,接下来怎么使程序运作起来的问题了。

这其中涉及到了一些知识,主要是那几个模块的使用,还有因为发送给服务器信息和服务器返回的信息都是bytes,

因此还有一些python关于bytes类型的资料

我把我在查资料时觉得不错的资料列一下吧

socket模块的介绍:http://blog.csdn.net/rebelqsp/article/details/22109925

python3 bytes与str的区别:http://www.ituring.com.cn/article/1116

关于int.to_bytes函数的官方文档:https://translate.google.com/translate?depth=1&hl=zh-CN&prev=search&rurl=translate.google.com.hk&sl=en&sp=nmt4&u=https://docs.python.org/3/library/stdtypes.html#int.to_bytes

signal模块的介绍:http://blog.sina.com.cn/s/blog_c2839d2a0102x3j1.html

还有就是多进程的模块,也就是multiprocessing模块,网上都写的差不多,大家可以自己去搜搜。

最后一点很关键的一点,在程序写完后让它运行,发现在python自带的IDLE中没反应,就好像是好几个函数没用一样。

后面才发现要找到你写的代码的那个文件,也就是带.py的文件。点开它,弹幕就会出来了,是在windos下的cmd里才会显示出来。

经过测试

显示出的弹幕,在弹幕量大的时候好像显示得不完全,有些用户的弹幕获取不到?(不知道是不是我看错了没有),不过一般的弹幕量还是可以获取到的。

完整代码:

import re
import socket
import signal
import multiprocessing
import timeclient = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
port = 8602 # 端口8601、8602、12601、12602这几个端口号都是,但有时候有号些获取不到弹幕的信息,每个都试下总有一个可以
host = socket.gethostbyname('openbarrage.douyutv.com')
client.connect((host,port))danmu = re.compile(b'txt@=(.+?)/')
user_id = re.compile(b'nn@=(.+?)/')def send_request_msg(msgstr):msg = msgstr.encode('utf-8')#协议规定所有协议内容均为 UTF-8 编码data_lenth = len(msg) + 8#data_lenth表示整个协议头的长度(消息长度),包括数据部分和头部,len(msg)就是数据部分,8就是头部的长度code = 689#根据协议消息类型字段用689msghead = int.to_bytes(data_lenth,4,'little') + int.to_bytes(data_lenth,4,'little') + int.to_bytes(code,4,'little')#msghead是按照斗鱼第三方协议构造的协议头#前2段表示的是消息长度,最后一个是消息类型#这里还有个值得注意的一点,发送给服务器的类型和服务器返回的类型都是bytes,因此要把数据信息通过int.to_bytes()变成bytesclient.send(msghead)#发送协议头client.send(msg)#发送消息请求def get_danmu(roomid):denglu_msg = 'type@=loginreq/roomid@={}/\0'.format(roomid)#登录请求消息,最后面的'\0',是协议规定在数据部分结尾必须是'\0'send_request_msg(denglu_msg)join_room_msg = 'type@=joingroup/rid@={}/gid@=-9999/\0'.format(roomid)#加入房间分组消息send_request_msg(join_room_msg)while True:data = client.recv(1024)#这个data就是服务器向客户端发送的消息#具体的信息可以看斗鱼弹幕第三方接入协议danmu_username = re.findall(user_id,data)dammu_content = re.findall(danmu,data)#print(data)if not data:breakelse:for i in range(0,len(danmu_username)):try:print('[{}]:{}'.format(danmu_username[i].decode('utf-8'),dammu_content[i].decode('utf-8')))#返回的数据是bytes型,所以要用decode方法来解码except:continuedef keeplive():#维持与后台的心跳#关于心跳消息,协议中有详细的解释while True:live_msg = 'type@=keeplive/tick@=' + str(int(time.time())) + '/\0'send_request_msg(live_msg)time.sleep(15)def logout():out_msg = 'type@=logout/'send_request_msg(out_msg)print('已退出服务器!')def signal_handler(signal,frame):#捕捉ctrl + c的信号,即signal.SIGINTp1.terminate()#结束进程p2.terminate()#结束进程logout()if __name__ == '__main__':roomid = 74751#房间号,主播开播才能获取到信息signal.signal(signal.SIGINT,signal_handler)p1 = multiprocessing.Process(target = get_danmu,args = (roomid,))p2 = multiprocessing.Process(target = keeplive)p1.start()p2.start()

写这么个东西没我想的那么容易,也用了不少的时间。不过也还是弄出来了,

可能写的也不是很好吧,但每次写一个新东西也是一次新的挑战,

也在其中学到了不少的东西。可能我的理解也表达不是那么清楚,可能也有一些错误,如果有发现错误的地方欢迎各位指正

python爬虫----简单的抓取斗鱼弹幕相关推荐

  1. python爬虫代码房-Python爬虫一步步抓取房产信息

    原标题:Python爬虫一步步抓取房产信息 前言 嗯,这一篇文章更多是想分享一下我的网页分析方法.玩爬虫也快有一年了,基本代码熟悉之后,我感觉写一个爬虫最有意思的莫过于研究其网页背后的加载过程了,也就 ...

  2. 通过Python爬虫按关键词抓取相关的新闻

    前言 本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途 如今各大网站的反爬机制已经可以说是到了丧心病狂的程度,比如大众点评的字符加密.微博的登录验证等.相比较而言,新闻网站的反爬机制 ...

  3. python爬虫关键词抓手机号_通过Python爬虫按关键词抓取相关的新闻

    前言 本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. 如今各大网站的反爬机制已经可以说是到了丧心病狂的程度,比如大众点评的字符加 ...

  4. Python爬虫项目:抓取智联招聘信息

    来自https://mp.weixin.qq.com/s/0SzLGqv2p0-IWSN3r8bOHA ''' Python爬虫之五:抓取智联招聘基础版 该文件运行后会产生一个代码,保存在这个Pyth ...

  5. python爬虫妹子图抓取

    python爬虫妹子图抓取 目标网址:图片地址 我的github地址:超链接 可以自行感受一下,我就不说了,重点是学习代码,不是图片 #! /usr/bin/python3 # -*- coding: ...

  6. python 爬虫学习:抓取智联招聘网站职位信息(二)

    在第一篇文章(python 爬虫学习:抓取智联招聘网站职位信息(一))中,我们介绍了爬取智联招聘网站上基于岗位关键字,及地区进行搜索的岗位信息,并对爬取到的岗位工资数据进行统计并生成直方图展示:同时进 ...

  7. Scrapy Python爬虫实战:抓取知乎问题下所有回答!

    今天趁摸鱼的时候玩了会知乎,突然看到一个非常有意思的话题 单身狗不知道还能干什么,所以特地把这些数据都抓下来,看看不除了第二杯半价还能干什么? 创建scrapy项目 前面教程概念讲的我嘴都麻了,估计大 ...

  8. 通过websocket抓取斗鱼弹幕和礼物消息

    1.斗鱼弹幕协议 到斗鱼官方开放平台看斗鱼通讯协议,网址"斗鱼开放平台",登录后可查看 所以根据斗鱼协议做编码函数: 1 def msg_encode(msg):2 #消息以 \0 ...

  9. 爬虫python书籍-Python爬虫案例:抓取豆瓣编程类高评分书籍

    对于很多正在学习计算机的朋友来说,选择合适的学习材料是非常重要的. 本文将通过 Python 来爬取豆瓣编程类评分大于 9.0 的书籍. 此案例很适合入门爬虫的朋友学习,总共也就 3 个函数. 下图是 ...

最新文章

  1. 微服务架构及其最重要的 10 个设计模式!
  2. tensorflow随笔-简单CNN(卷积深度神经网络结构)
  3. 呼叫我,或异步REST
  4. spring技术内幕——深入解析spring架构与设计原理
  5. 隔一段时间查找一次 golang_剑指 offer-04 二维数组中的查找
  6. proc文件系统探索 之 以数字命名的目录
  7. urllib携带登录信息
  8. 开头的单词_为什么U开头的单词前面有时加a,有时加an----高考语法知识运用
  9. html5 mid格式音乐,html5中audio支持音频格式的解决方法
  10. 2021智能零售领域最具商业合作价值企业盘点
  11. 平面设计学习需要会哪些知识
  12. 游戏引擎架构----动画
  13. 【翻译论文】An Architecture Combining Convolutional Neural Network (CNN) and Support Vector Machine (SVM)
  14. 【mmdetection】mmdetection学习率设置
  15. 原型设计工具——“墨刀”的介绍与基本教程
  16. 安装 配置 Nginx
  17. hdu吃糖果解题报告
  18. 【1066】满足条件的数累加
  19. yolov3的缺点_YOLOV3问答式解读
  20. MySQL字符集设定与查询

热门文章

  1. 手把手教你开发IOT设备
  2. IoT设备与手机App之间如何实现实时消息通信——业务场景最佳实践
  3. Nginx--secure_link和geoip_module
  4. 鸿蒙手机摄影,鸿蒙系统正式亮相 华为:手机随时可以使用
  5. leetcode(15):华为HJ95||人民币转换
  6. Citrix_XenDesktop 搭建过程
  7. 人工智能领域技术,主要包含了哪些核心技术?
  8. php友情链接大于3换行,友情链接11大欺骗方法
  9. 《当程序员的那些狗日日子》后记
  10. 关于XAMPP下载安装的一些问题