Month: July 2015

B站官方群和B站的弹幕连接

B站官方群和B站的弹幕连接

【完成!】 稀里哗啦直传反馈群的日常 http://www.bilibili.com/video/av2594921/ 给那些好奇的从B站来的小伙伴们截图     解释一下为什么B站到QQ和QQ到B站都有延迟——   为啥B站到QQ延迟非常大? 因为B站的弹幕都是XML文件,因为B站用户有很多,所以这些文件都要在全世界每一个B站缓存服务器缓存一下,到指定时间再更新。这个时间经常是好几分钟,也就是说有了新弹幕之后需要好长好长时间之后才会反应在弹幕文件里。我这儿每五秒钟抓取一次查看是否有最新的弹幕好能发送到QQ群里,但是也奈何不了B站官方3-4分钟更新一次弹幕文件……所以造成了很多时候B站弹幕到QQ群里需要3-4分钟。 为啥QQ到B站有少量延迟并且有吞消息情况发生? 因为B站只允许间隔至少5秒发一条弹幕,否则会封号。我们已经尽量压缩消息了,但是由于源消息(直接发送弹幕到B站)经常掉节操(因为群里的人一般都没有节操),所以我们改用了类似Base64的“加密”方法防止掉节操。Base64的加密是3个8字节的字符转换为4个6进制的。由于B站一条弹幕最多允许100字节,所以说理论100字节的弹幕最多可以装加密前消息(100/4) * 3 = 75字节。一个汉字3字节,于是乎经常会有消息排队等待发送。为了防止消息过快发送导致账号被封,我们设置的是6秒发送一次弹幕。 另外,若消息队列或发送队列超过100条消息,那么会把前面的50条消息删掉(虽然到现在为止这个情况还没出现过)。 另外,B站的播放器获取最新弹幕使用了TCP,我通过抓包发现(底下有说)这个很不稳定,B站不会给播放器传过来所有的新弹幕(10条新弹幕大概传6-7条左右),所以导致了有的时候QQ上说话发送到B站吞了消息。 综上原因导致了B站到QQ和QQ到B站均有很大的延迟,并且B站端经常吞消息。 希望大家理解吧,毕竟这不是我能控制的——我完全是用B站的协议完成的,若是B站协议不支持那些东西那我也就没有办法……   7月下旬的时候,突然脑洞大开,跟好基机友 B站@多鲁基X铃 突发奇想,想到了一个pipe,来连接B站弹幕和QQ群聊天;让B站弹幕版聊可以同步到QQ群里,QQ群里的聊天也可以同步到B站上。 说干就干。 刚开始就有一个自己写的目前来讲比较稳定的,基于SmartQQ协议的机器人(SmartMiao,在我当初的博客中有提到过)。这个机器人可以根据不同的群来进行不同的操作,并且对不同的请求可以给出不同的回答。最重要的是,支持随时添加Python(当然用C++写Python插件也没问题)编写的模块——这是这个作品最需要的可扩展性。 现在,要对B站开刀了。 首先,先对B站的登录进行模拟。 这个跟当初搞QQ协议比简直是小菜一碟,真是不值得一提…… 再然后,就是B站各种协议的事儿了。 接着抓网页,发现B站是两个东西——一个是avid,另一个是c(omment)id. 抓起来也方便,页面读读就明白了。 再之后,发两条弹幕,看看发送弹幕协议是啥样的。 仍然是那样的,不值得一提…… 总之就是把开发者工具一开开,所有东西就真儿真儿的映现在眼前了……   之后做了一个bilimiao,负责一切后台的东西,可以想象为*nix的Kernel内核层。不是不可以直接访问,而是因为各种各样的原因访问起来不方便。 然后做了个QtoBPipe(负责QQ发过来的消息队列加密和队列,因为B站每次发源数据都会掉节操,毕竟B站Q群里没有什么节操……队列是因为B站只能每5秒发送一次弹幕,否则么……这个号就Byebye了)和BtoQPipe(负责处理B站传过来的消息,查看其发送时间,若大于之前的发送时间则发送到Q群;另,只取最后的最多不超过5条弹幕发送到Q群),负责进行双向的交流——它们都是值守进程,构筑在bilimiao上,作为一个Shell层。 之后就是最上层的SmartMiao的模块了。只要有消息,就会触发发送消息模块发送消息到QtoBPipe进行处理;同时这个模块也隐含了一个模块使其从BtoQPipe获取消息进行处理。这个模块是While True的死循环,并且同时只会有一个存在(通过非阻塞判断是否成功获得锁,若获取成功则为Chosen One进行死循环,若不成功就不是Chosen One退出。换句话说,第一次获取到消息之后的触发的那个程序模块就是Chosen One)。 然后就是你们看到的东西啦~ 两方互相聊(zhuang)天(bi),互相进行友(feng)好(sheng)坦(shui)诚(qi)地交流。   但是呢,有个很严重的问题。 B站的弹幕是有缓存的。 每次从XML获取到弹幕都可能得最多卡住10分钟才能获取到最新的弹幕。 有的时候1分钟,有的时候10分钟,谁受得了啊。 于是乎,开始研究B站黑科技。 通过抓包(说得简单,花了我N个小时找包然后读明白协议,毕竟不知道B站到底发送包到哪个IP里面去了)得出来B站的Flash播放器会使用TCP来跟B站的服务器进行通讯获取最新一条弹幕。 抓来抓去,发现了B站这个更不稳定,经常丢消息。 我看了一眼,10条消息至少能丢3-5条……算了就弃用了,毕竟这个要的是稳定为先。 总之,现在就大概是这样了~…

Read More Read More

票.今天的数据抓取

票.今天的数据抓取

好久没写博客了。 回国了,放假了,也是时候写篇博客散散心了。 作为一个抓取数据的网站,抓取数据是最重要的一个环节。 piao.today是如何做到稳定抓取数据的呢? 余票趋势和实时余票功能 他们抓取数据的难点都分别在哪里呢? 让我们来盘点一下。   首先,说说余票趋势。 余票趋势最重要的是后台抓取,不可避免地需要谈到Worker进程。 本站的抓取分任务分发者和工作者。分发者负责从数据库中查找需要抓取的区间,然后分发给抓取的工作者。 在实践过程中,男性朋友们会遇到worker进程由于控制不当系统问题而提前射x停止工作(被系统莫名kill掉)。 所以,我们需要用crontab来进行一个小脚本,每隔一段时间查看worker数量,若不足则增加worker数量到一个数值。 这些脚本的用途就是用来获取当前运行了多少worker,若不足则重新添加。 因为Python的稳定性(而且作为后台运行的程序来说,只要内存足够,不管多少worker进程都放得下),所以没啥大问题。 但是,最近将实时余票功能升级了一下,改成允许用户抓取多日(预售期)余票(比如),发现服务器经常出现502(Bad Gateway)或者504(Gateway Timeout)错误。 这说明,我的php-fpm和Nginx的设置有问题,没有考虑到大并发和长连接的问题。 如果用户中途关闭了窗口,经常一个fpm进程就会卡在那里不知所措,被水淹没。 那么会导致整个站点因为fpm数量不够而卡死。 现在分散到多个vps上——四个服务器,三个在香港一个在日本,避免了把整个站带坏。 因为这些服务器距离国内都不远,所以抓取实时余票反馈给用户会很快。 以后应该研究一下对于这种情况的根本解决措施。 最近有时间先把筛选搞了吧。 总之吧,先mark下。 等着过两天驾照下来了好好研究研究。