python爬虫----简单的抓取斗鱼弹幕
近几年来直播越来越火,看直播也成为了人们生活的娱乐项目
个人也是比较喜欢看直播,看着主播的搞笑的操作和弹幕不时会开怀大笑。
于是就想能不能把弹幕抓取下来,带着这个问题我就点开了一个直播间。按照以前学过的方法好像根本没有办法弄到弹幕那一块,
于是赶紧去网上查,发现网上有不少人已经做了。呃......怎么说,大概了解了获取弹幕的原理,就是通过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爬虫----简单的抓取斗鱼弹幕相关推荐
- python爬虫代码房-Python爬虫一步步抓取房产信息
原标题:Python爬虫一步步抓取房产信息 前言 嗯,这一篇文章更多是想分享一下我的网页分析方法.玩爬虫也快有一年了,基本代码熟悉之后,我感觉写一个爬虫最有意思的莫过于研究其网页背后的加载过程了,也就 ...
- 通过Python爬虫按关键词抓取相关的新闻
前言 本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途 如今各大网站的反爬机制已经可以说是到了丧心病狂的程度,比如大众点评的字符加密.微博的登录验证等.相比较而言,新闻网站的反爬机制 ...
- python爬虫关键词抓手机号_通过Python爬虫按关键词抓取相关的新闻
前言 本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. 如今各大网站的反爬机制已经可以说是到了丧心病狂的程度,比如大众点评的字符加 ...
- Python爬虫项目:抓取智联招聘信息
来自https://mp.weixin.qq.com/s/0SzLGqv2p0-IWSN3r8bOHA ''' Python爬虫之五:抓取智联招聘基础版 该文件运行后会产生一个代码,保存在这个Pyth ...
- python爬虫妹子图抓取
python爬虫妹子图抓取 目标网址:图片地址 我的github地址:超链接 可以自行感受一下,我就不说了,重点是学习代码,不是图片 #! /usr/bin/python3 # -*- coding: ...
- python 爬虫学习:抓取智联招聘网站职位信息(二)
在第一篇文章(python 爬虫学习:抓取智联招聘网站职位信息(一))中,我们介绍了爬取智联招聘网站上基于岗位关键字,及地区进行搜索的岗位信息,并对爬取到的岗位工资数据进行统计并生成直方图展示:同时进 ...
- Scrapy Python爬虫实战:抓取知乎问题下所有回答!
今天趁摸鱼的时候玩了会知乎,突然看到一个非常有意思的话题 单身狗不知道还能干什么,所以特地把这些数据都抓下来,看看不除了第二杯半价还能干什么? 创建scrapy项目 前面教程概念讲的我嘴都麻了,估计大 ...
- 通过websocket抓取斗鱼弹幕和礼物消息
1.斗鱼弹幕协议 到斗鱼官方开放平台看斗鱼通讯协议,网址"斗鱼开放平台",登录后可查看 所以根据斗鱼协议做编码函数: 1 def msg_encode(msg):2 #消息以 \0 ...
- 爬虫python书籍-Python爬虫案例:抓取豆瓣编程类高评分书籍
对于很多正在学习计算机的朋友来说,选择合适的学习材料是非常重要的. 本文将通过 Python 来爬取豆瓣编程类评分大于 9.0 的书籍. 此案例很适合入门爬虫的朋友学习,总共也就 3 个函数. 下图是 ...
最新文章
- 微服务架构及其最重要的 10 个设计模式!
- tensorflow随笔-简单CNN(卷积深度神经网络结构)
- 呼叫我,或异步REST
- spring技术内幕——深入解析spring架构与设计原理
- 隔一段时间查找一次 golang_剑指 offer-04 二维数组中的查找
- proc文件系统探索 之 以数字命名的目录
- urllib携带登录信息
- 开头的单词_为什么U开头的单词前面有时加a,有时加an----高考语法知识运用
- html5 mid格式音乐,html5中audio支持音频格式的解决方法
- 2021智能零售领域最具商业合作价值企业盘点
- 平面设计学习需要会哪些知识
- 游戏引擎架构----动画
- 【翻译论文】An Architecture Combining Convolutional Neural Network (CNN) and Support Vector Machine (SVM)
- 【mmdetection】mmdetection学习率设置
- 原型设计工具——“墨刀”的介绍与基本教程
- 安装 配置 Nginx
- hdu吃糖果解题报告
- 【1066】满足条件的数累加
- yolov3的缺点_YOLOV3问答式解读
- MySQL字符集设定与查询