基于asyncio 异步协程框架实现收集B站直播弹幕


Posted in Python onSeptember 11, 2016

前言

虽然标题是全站,但目前只做了等级 top 100 直播间的全天弹幕收集。

弹幕收集系统基于之前的B 站直播弹幕姬 Python 版修改而来。具体协议分析可以看上一篇文章。

直播弹幕协议是直接基于 TCP 协议,所以如果 B 站对类似我这种行为做反制措施,比较困难。应该有我不知道的技术手段来检测类似我这种恶意行为。

我试过同时连接 100 个房间,和连接单个房间 100 次的实验,都没有问题。>150 会被关闭链接。

直播间的选取

现在弹幕收集系统在选取直播间上比较简单,直接选取了等级 top100。

以后会修改这部分,改成定时去 http://live.bilibili.com/all 查看新开播的直播间,并动态添加任务。

异步任务和弹幕存储

收集系统仍旧使用了 asyncio 异步协程框架,对于每一个直播间都使用如下方法来加进 loop 中。

danmuji = bilibiliClient(url, self.lock, self.commentq, self.numq)
task1 = asyncio.ensure_future(danmuji.connectServer())
task2 = asyncio.ensure_future(danmuji.HeartbeatLoop())

其实若将心跳任务 HeartbeatLoop 放入 connectorServer 中去启动,代码看起来更优雅一些。但这么做是因为我需要维护一个任务列表,后面会有描述。

在弹幕存储上我花了些时间选择。

数据库存储是一个同步 IO 的过程,Insert 的时候会阻塞弹幕收集的任务。虽然有 aiomysql 这种异步接口,但配置数据库太麻烦,我的设想是这个小系统能够方便地部署。

最终我选择使用自带的 sqlite3。但 sqlite3 无法做并行操作,故开了一个线程单独进行数据库存储。在另一个线程中,100 * 2 个任务搜集所有的弹幕、人数信息,并塞进队列 commentq, numq 中。存储线程每隔 10s 唤醒一次,将队列中的数据写进 sqlite3 中,并清空队列。

在多线程和异步的配合下,网络流量没有被阻塞。

可能的连接失败场景处理

弹幕协议是直接基于 TCP,位与位直接关联性较强,一旦解析错误,很容易就抛 Exception(个人感觉,虽然 TCP 是可靠传输,但B站服务器自身发生错误也是有可能的)。所以有必要设计一个自动重连机制。

在 asyncio 文档中提到,

Done means either that a result / exception are available, or that the future was cancelled.

函数正常返回、抛出异常或者是被 cancel,都会退出当前任务。可以使用 done() 来判断。

每一个直播间对应两个任务,解析任务是最容易挂的,但并不会影响心跳任务,所以必须找出并将对应心跳任务结束。
在创建任务的时候使用字典记录每个房间的两个任务,

self.tasks[url] = [task1, task2]

在运行过程中,每隔 10s 做一次检查,

for url in self.tasks:
  item = self.tasks[url]
  task1 = item[0]
  task2 = item[1]
  if task1.done() == True or task2.done() == True:
    if task1.done() == False:
      task1.cancel()
    if task2.done() == False:
      task2.cancel()
    danmuji = bilibiliClient(url, self.lock, self.commentq, self.numq)
    task11 = asyncio.ensure_future(danmuji.connectServer())
    task22 = asyncio.ensure_future(danmuji.HeartbeatLoop())
    self.tasks[url] = [task11, task22]

实际我只见过一次任务失败的场景,是因为主播房间被封了,导致无法进入直播间。

结论

  1. B站人数是按照连接弹幕服务器的链接数量统计的。通过操纵链接量,可以瞬间增加任意人数观看,有商机?
  2. 运行的这几天中,发现即使大部分房间不在直播,也能有 >5 的人数,包括凌晨。我只能猜测也有和我一样的人在 24h 收集弹幕。
  3. top100 平均一天 40M 弹幕数据。
  4. 收集的弹幕能做什么?还没想好,可能可以拿来做用户行为分析 -_^

最后附上本源码的GITHUB地址 https://github.com/lyyyuna/bilibili_danmu_colloector

Python 相关文章推荐
Python中的多重装饰器
Apr 11 Python
Python多线程下载文件的方法
Jul 10 Python
Python输出各行命令详解
Feb 01 Python
PyQt5打开文件对话框QFileDialog实例代码
Feb 07 Python
Python读写docx文件的方法
May 08 Python
Python音频操作工具PyAudio上手教程详解
Jun 26 Python
pandas factorize实现将字符串特征转化为数字特征
Dec 19 Python
python多线程使用方法实例详解
Dec 30 Python
python实现3D地图可视化
Mar 25 Python
tensorflow pb to tflite 精度下降详解
May 25 Python
在Python中实现字典反转案例
Dec 05 Python
Python实现的扫码工具居然这么好用!
Jun 07 Python
asyncio 的 coroutine对象 与 Future对象使用指南
Sep 11 #Python
Python中使用asyncio 封装文件读写
Sep 11 #Python
Python 如何访问外围作用域中的变量
Sep 11 #Python
Python优化技巧之利用ctypes提高执行速度
Sep 11 #Python
Python 中的with关键字使用详解
Sep 11 #Python
Python冒泡排序注意要点实例详解
Sep 09 #Python
通过5个知识点轻松搞定Python的作用域
Sep 09 #Python
You might like
关于session在PHP5的配置文件中的详细设置参数说明
2011/04/20 PHP
ThinkPHP的I方法使用详解
2014/06/18 PHP
JavaScript 中的事件教程
2007/04/05 Javascript
js去字符串前后空格5种实现方法及比较
2013/04/03 Javascript
jQuery之排序组件的深入解析
2013/06/19 Javascript
js分页代码分享
2014/04/28 Javascript
javascript轻量级库createjs使用Easel实现拖拽效果
2016/02/19 Javascript
JavaScript新增样式规则(推荐)
2016/07/19 Javascript
Angular简单验证功能示例
2017/12/22 Javascript
nginx部署访问vue-cli搭建的项目的方法
2018/02/12 Javascript
原生JS实现的放大镜特效示例【测试可用】
2018/12/08 Javascript
vue写h5页面的方法总结
2019/02/12 Javascript
基于Vue2实现移动端图片上传、压缩、拖拽排序、拖拽删除功能
2021/01/05 Vue.js
[01:31]完美与DOTA2历程
2014/07/31 DOTA
Python中input和raw_input的一点区别
2014/10/21 Python
Python探索之SocketServer详解
2017/10/28 Python
用Python一键搭建Http服务器的方法
2018/06/01 Python
Python采集猫眼两万条数据 对《无名之辈》影评进行分析
2018/12/05 Python
python通过http下载文件的方法详解
2019/07/26 Python
Pycharm 字体大小调整设置的方法实现
2019/09/27 Python
windows系统Tensorflow2.x简单安装记录(图文)
2021/01/18 Python
CSS3 绘制BMW logo实的现代码
2013/04/25 HTML / CSS
css3 transform及原生js实现鼠标拖动3D立方体旋转
2016/06/20 HTML / CSS
美国隐形眼镜零售商:LensPure
2019/03/10 全球购物
Gerry Weber德国官网:优质女性时装,德国最大的时装公司之一
2019/11/02 全球购物
北承题目(C++)
2012/05/16 面试题
英文版网络工程师求职信
2013/10/28 职场文书
广播节目策划方案
2014/05/23 职场文书
基层党员公开承诺书
2014/05/29 职场文书
社区春季防火方案
2014/06/02 职场文书
2014党员学习《反腐倡廉警示教育读本》思想汇报
2014/09/13 职场文书
领导干部个人对照检查材料(群众路线)
2014/09/26 职场文书
2014标准社保办理委托书
2014/10/06 职场文书
2015年护士节活动总结
2015/02/10 职场文书
小学生读书笔记范文
2015/06/30 职场文书
关于flex 上下文中自动 margin的问题(完整例子)
2021/05/20 HTML / CSS