如何获取斗鱼直播间的弹幕信息?
如何获取如图红色框中的弹幕信息呢?想做一些基于弹幕信息的二次开发。

回复内容:
在参考顶楼的回答和评论后,正确获取到了弹幕,来回报下社会,代码已经放在Github上了! douyu/danmu.cc at master · fishioon/douyu · GitHub代码是C写的,本来用的python,感觉C更好用(在处理数据的时候)。
比较喜欢看yyf的dota2直播,但是最近yyf经常吹B,说有网友弹幕问“枫哥枫哥,你的XX怎么这么厉害啊”,水友们纷纷表示不信,所以就想着把弹幕爬下来,同时还有那些说赢了直播吃翔的,我通通都要记录下来!!!
回答正题,那我们该如何弄清楚这个协议呢?
弹幕属于实时消息,第一反应应该用websocket实现,打开chrome,F12,websocket中竟然找不到!那估计是通过Flash实现了。前端不熟,找了半天也没找到JS实现代码,只好祭出wireshark来分析了。
看了顶楼的提示,在wireshark中查看端口为8601的数据包,如下图所示。

前三个数据包就是TCP的三次握手啦,复习下;接着我们看第四个数据包,如下图所示

struct {
int len; //数据包长度
int code; //经抓包发现该字段一直与len字段一致
int magic; //不知道啥意思,发现请求都是0x2b1, 返回都是0x2b2
char content[0]; //消息具体内容
}
从图中的内容中可以看到:
1. 登录弹幕服务器: "type@=loginreq/username@%s=/password@=%s/roomid@=%d/ct@=2/",输入自己的账号密码(经测试发现,账号密码随便填都能成功),要看的房间id,如yyf的房间id为52428
通过socket发送上面的内容后,你回收到这样的一条数据,格式与发送格式一样:
“type@=loginres/userid@=0/roomgroup@=0/pg@=0/sessionid@=0/username@=/nickname@=/live_stat@=0/is_illegal@=0/npv@=0/best_dlev@=0/cur_lev@=0/”,没发现有啥有用的数据。
2. 收到上面的消息后,这时候要加入一个组,格式如下:
"type@=joingroup/rid@=%d/gid@=%d/",rid就是房间id,要注意的问题来了:
gid应该是group id,登录不同房间该id都不一样,每次我都是抓包来查看该id是多少,有知情人告诉我吗?(一楼评论中也提到这个问题)
发送上面的消息后,我们就可以安心的接收数据了,然后从数据中提取我们想要的就可以了,其中很多数据都不懂啥意思。
最后我们看下yyf房间的弹幕哈!(节奏带的飞起)

Update 20160220 : 更新Python客户端,增加直播视频的Live获取,以及Mac平台下面的Mplayer的视频播放.代码均放在Github上面. GitHub - twocucao/danmu.fm: douyutv danmu 斗鱼TV 弹幕助手
由于zhihu没有法子贴动态图,那只好移步到我的博客一看了.(看博客之前记得点赞╮(╯_╰)╭)
Python程序员如何优雅的看斗鱼TV
===================优雅的看斗鱼TV的分割线==================================
-1.如果不想看长文,直接使用.则在安装好Python3或者Ruby2.0以上版本.
<span class="c">#安装Python客户端</span> pip3 install danmu.fm <span class="c"># 比如主播的直播间</span> danmu.fm http://www.douyutv.com/16789 <span class="c">#或者</span> danmu.fm 16789 <span class="c">#安装Ruby客户端</span> gem install danmu <span class="c">#使用</span> danmu douyu <span class="o">[</span>room_id/url<span class="o">]</span> <span class="c">#比如</span> danmu douyu qiuri danmu douyu http://www.douyutv.com/13861
Update:2016.1.16
总结在博客里:抓取斗鱼直播弹幕
Github 项目地址:brucezz/DouyuCrawler
欢迎去提各种 issue & PR (代码水平不高)...
/********************************************************************************************/
Update:2016.1.14
最近几天会把 Java 项目发布到 Github 上面,大家提提意见 :)
/********************************************************************************************/
之前看到这个问题,感觉挺好玩的,就研究了下。
照着前面的思路,抓包分析。其他几位的回答,基本能抓到弹幕数据了,但是其中一个参数gid,需要手动抓包得到。我也查看了浏览器加载的js文件,没看到相关线索。最后看到排名第一的回答评论里有人说可以通过请求页面里server_config的ip。
然后我就顺着这条线索探索下去了。
具体过程如下:
先获取到直播页面中的server_config相关字段,发现是经过urlencode的。

UrlEncode编码/UrlDecode解码
JSON在线编辑
就变成这样:
<span class="p">[{</span><span class="nt">"ip"</span><span class="p">:</span><span class="s2">"119.90.49.107"</span><span class="p">,</span><span class="nt">"port"</span><span class="p">:</span><span class="s2">"8035"</span><span class="p">},{</span><span class="nt">"ip"</span><span class="p">:</span><span class="s2">"119.90.49.102"</span><span class="p">,</span><span class="nt">"port"</span><span class="p">:</span><span class="s2">"8008"</span><span class="p">},{</span><span class="nt">"ip"</span><span class="p">:</span><span class="s2">"119.90.49.110"</span><span class="p">,</span><span class="nt">"port"</span><span class="p">:</span><span class="s2">"8050"</span><span class="p">},{</span><span class="nt">"ip"</span><span class="p">:</span><span class="s2">"119.90.49.104"</span><span class="p">,</span><span class="nt">"port"</span><span class="p">:</span><span class="s2">"8020"</span><span class="p">},{</span><span class="nt">"ip"</span><span class="p">:</span><span class="s2">"119.90.49.107"</span><span class="p">,</span><span class="nt">"port"</span><span class="p">:</span><span class="s2">"8034"</span><span class="p">},{</span><span class="nt">"ip"</span><span class="p">:</span><span class="s2">"119.90.49.92"</span><span class="p">,</span><span class="nt">"port"</span><span class="p">:</span><span class="s2">"8059"</span><span class="p">},{</span><span class="nt">"ip"</span><span class="p">:</span><span class="s2">"119.90.49.95"</span><span class="p">,</span><span class="nt">"port"</span><span class="p">:</span><span class="s2">"8071"</span><span class="p">},{</span><span class="nt">"ip"</span><span class="p">:</span><span class="s2">"119.90.49.101"</span><span class="p">,</span><span class="nt">"port"</span><span class="p">:</span><span class="s2">"8001"</span><span class="p">},{</span><span class="nt">"ip"</span><span class="p">:</span><span class="s2">"119.90.49.93"</span><span class="p">,</span><span class="nt">"port"</span><span class="p">:</span><span class="s2">"8063"</span><span class="p">},{</span><span class="nt">"ip"</span><span class="p">:</span><span class="s2">"119.90.49.91"</span><span class="p">,</span><span class="nt">"port"</span><span class="p">:</span><span class="s2">"8053"</span><span class="p">}]</span>
最近斗鱼修改了弹幕格式,大概长这个样子
<span class="n">b</span><span class="s">'</span><span class="se">\x81\x00\x00\x00\x81\x00\x00\x00\xb2\x02\x00\x00</span><span class="s">type@=chatmsg/rid@=9401/uid@=12635840/nn@=</span><span class="se">\xe8\xb6\x85\xe8\xb6\x8a\xe7\xa5\x9e\xe7\x9a\x84</span><span class="s">boy/txt@=</span><span class="se">\xe6\x89\x93\xe8\x84\xb8\xe5\x90\xa7</span><span class="s">/cid@=20e4e3fe427e410c67c5010000000000/level@=5/</span><span class="se">\x00</span><span class="s">'</span>

随便抓了100个房间大概半小时。
优雅的抓出那些说“屎尿屁”的“精神周星驰”:
(那么大家都发现了,疯狂说这些一般都是20级以下的人。斗鱼要到20级大概是充值3000-4000左右好像。那么你们明白什么了吗)




最后还有更好玩的(大家来找壕,看看壕都喜欢去什么房间):

当然编程的方式也要优雅:Python
至于方法,最高赞已经很干净清晰了的解答了,我这里做小小补充。
其实不需要那么多工序,用socket直接3个命令就可以了:
下面伪代码:
client_danmu = socket.socket(socket.AF_INET, socket.SOCK_STREAM) #在客户端开启心跳维护 client_danmu.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1) #官方弹幕服务器'openbarrage.douyutv.com' SERVER = socket.gethostbyname('openbarrage.douyutv.com') PORT = 8601 client_danmu.connect((SERVER,PORT)) client_danmu.settimeout(2) #记得设置延迟,不然卡着recv #这里发的要处理下发送内容,用最高赞的方法获取封包格式就好了 封包1 = 'type@=loginreq/username@=visitor1234567/password@=/roomid@=房间号/' #登陆弹幕服务器 client_danmu.send(封包1) 封包2 = 'type@=joingroup/rid@=房间号/gid@=-9999/' #加入弹幕组,这里要注意,gid就是弹幕组号。-9999是斗鱼开放的第三方获取弹幕的组别。是能获取所有弹幕的。因为有些主播动辄几十万人,那弹幕量如果都发给所有用户,那卡死用户事小,斗鱼自己流量事大啊。所以一般都是分组发送,所以你平时在浏览器看的并不一定是所有弹幕。用-9999这个组别号是可以获取所有的 client_danmu.send(封包2) #这里开始就是用while循环获取弹幕了,记得大概每30秒发一个心跳包过去。 封包3 = 'type@=mrkl/' client_danmu.send(封包3)
是这样的,斗鱼的弹幕信息有个自己的服务器
http://danmu.douyutv.com 可以抓包看到,他通过TCP连接到斗鱼弹幕服务器,然后获取的信息,那么想要对它进行二次开发只需要模拟用户连接并登入弹幕服务器即可。
弹幕连接 OnConn (program):1 弹幕 UserLogin [type@=loginreq/username@=xxxx/password@=1234567890123456/roomid@=58718/] (program):1 弹幕 网络数据 [type@=loginres/userid@=0/roomgroup@=67108896/pg@=0/sessionid@=6/username@=/nickname@=/is_signined@=432003648/signin_count@=32756/s@=% ô/live_stat@=125387584/npv@=32756/] (program):1 弹幕登录成功 VM160:1 弹幕分组 [type@=joingroup/rid@=58718/gid@=0/] 2VM171:1 FMPNetStream连接状态:NetStream.Buffer.Full VM175:1 弹幕 网络数据 [type@=userenter/rid@=58718/gid@=0/userinfo@=id@A=4295897@Sname@A=auto_DJUziSYiJo@Snick@A=芙苏不语丶怪力乱神@Srg@A=1@Spg@A=1@Srt@A=1416480352@Sbg@A=0@Sweight@A=12800@Sstrength@A=51800@Scps_id@A=0@Sps@A=1@Sver@A=0@Sm_deserve_lev@A=0@S/] VM176:1 新用户进入信息: [id@=4295897/name@=auto_DJUziSYiJo/nick@=芙苏不语丶怪力乱神/rg@=1/bg@=0/pg@=1/rt@=1416480352/weight@=12800/strength@=51800/cps_id@=0/]
地址: 斗鱼弹幕抓取
代码:https://github.com/ndrlslz/DouyuBarrageTool 既然没人发nodejs版,那我就发一个吧
<span class="kd">var</span> <span class="nx">net</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">'net'</span><span class="p">);</span> <span class="kd">var</span> <span class="nx">uuid</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">'node-uuid'</span><span class="p">);</span> <span class="kd">var</span> <span class="nx">md5</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">'md5'</span><span class="p">);</span> <span class="kd">var</span> <span class="nx">request</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">'request'</span><span class="p">);</span> <span class="kd">var</span> <span class="nx">HOST</span> <span class="o">=</span> <span class="s1">'danmu.douyutv.com'</span><span class="p">;</span> <span class="kd">var</span> <span class="nx">PORT</span> <span class="o">=</span> <span class="mi">8602</span><span class="p">;</span> <span class="kd">function</span> <span class="nx">send</span><span class="p">(</span><span class="nx">socket</span><span class="p">,</span> <span class="nx">payload</span><span class="p">)</span> <span class="p">{</span> <span class="kd">var</span> <span class="nx">data</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Buffer</span><span class="p">(</span><span class="mi">4</span> <span class="o">+</span> <span class="mi">4</span> <span class="o">+</span> <span class="mi">4</span> <span class="o">+</span> <span class="nx">payload</span><span class="p">.</span><span class="nx">length</span> <span class="o">+</span> <span class="mi">1</span><span class="p">)</span> <span class="nx">data</span><span class="p">.</span><span class="nx">writeInt32LE</span><span class="p">(</span><span class="mi">4</span> <span class="o">+</span> <span class="mi">4</span> <span class="o">+</span> <span class="nx">payload</span><span class="p">.</span><span class="nx">length</span> <span class="o">+</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">);</span> <span class="c1">//length</span> <span class="nx">data</span><span class="p">.</span><span class="nx">writeInt32LE</span><span class="p">(</span><span class="mi">4</span> <span class="o">+</span> <span class="mi">4</span> <span class="o">+</span> <span class="nx">payload</span><span class="p">.</span><span class="nx">length</span> <span class="o">+</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">4</span><span class="p">);</span> <span class="c1">//code</span> <span class="nx">data</span><span class="p">.</span><span class="nx">writeInt32LE</span><span class="p">(</span><span class="mh">0x000002b1</span><span class="p">,</span> <span class="mi">8</span><span class="p">);</span> <span class="c1">//magic</span> <span class="nx">data</span><span class="p">.</span><span class="nx">write</span><span class="p">(</span><span class="nx">payload</span><span class="p">,</span> <span class="mi">12</span><span class="p">);</span> <span class="c1">//payload</span> <span class="nx">data</span><span class="p">.</span><span class="nx">writeInt8</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">4</span> <span class="o">+</span> <span class="mi">4</span> <span class="o">+</span> <span class="mi">4</span> <span class="o">+</span> <span class="nx">payload</span><span class="p">.</span><span class="nx">length</span><span class="p">);</span> <span class="c1">//end of string</span> <span class="nx">socket</span><span class="p">.</span><span class="nx">write</span><span class="p">(</span><span class="nx">data</span><span class="p">)</span> <span class="p">}</span> <span class="kd">function</span> <span class="nx">login</span><span class="p">(</span><span class="nx">socket</span><span class="p">,</span> <span class="nx">roomid</span><span class="p">,</span> <span class="nx">user</span><span class="p">,</span> <span class="nx">password</span><span class="p">)</span> <span class="p">{</span> <span class="kd">var</span> <span class="nx">req</span> <span class="o">=</span> <span class="s1">'type@=loginreq/username@='</span> <span class="o">+</span> <span class="nx">user</span> <span class="o">+</span> <span class="s1">'/password@='</span> <span class="o">+</span> <span class="nx">password</span> <span class="o">+</span> <span class="s1">'/roomid@='</span> <span class="o">+</span> <span class="nx">roomid</span><span class="p">;</span> <span class="nx">send</span><span class="p">(</span><span class="nx">socket</span><span class="p">,</span> <span class="nx">req</span><span class="p">);</span> <span class="p">}</span> <span class="kd">function</span> <span class="nx">getGroupServer</span><span class="p">(</span><span class="nx">roomid</span><span class="p">,</span> <span class="nx">callback</span><span class="p">)</span> <span class="p">{</span> <span class="nx">request</span><span class="p">({</span><span class="nx">uri</span><span class="o">:</span><span class="s1">'http://www.douyutv.com/'</span> <span class="o">+</span> <span class="nx">roomid</span><span class="p">},</span> <span class="kd">function</span><span class="p">(</span><span class="nx">err</span><span class="p">,</span> <span class="nx">resp</span><span class="p">,</span> <span class="nx">body</span><span class="p">)</span> <span class="p">{</span> <span class="kd">var</span> <span class="nx">server_config</span> <span class="o">=</span> <span class="nx">JSON</span><span class="p">.</span><span class="nx">parse</span><span class="p">(</span><span class="nx">body</span><span class="p">.</span><span class="nx">match</span><span class="p">(</span><span class="sr">/room_args = (.*?)\}\;/g</span><span class="p">)[</span><span class="mi">0</span><span class="p">].</span><span class="nx">replace</span><span class="p">(</span><span class="s1">'room_args = '</span><span class="p">,</span> <span class="s1">''</span><span class="p">).</span><span class="nx">replace</span><span class="p">(</span><span class="s1">';'</span><span class="p">,</span> <span class="s1">''</span><span class="p">));</span> <span class="nx">server_config</span> <span class="o">=</span> <span class="nx">JSON</span><span class="p">.</span><span class="nx">parse</span><span class="p">(</span><span class="nx">unescape</span><span class="p">(</span><span class="nx">server_config</span><span class="p">[</span><span class="s1">'server_config'</span><span class="p">]));</span> <span class="nx">callback</span><span class="p">(</span><span class="nx">server_config</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="nx">ip</span><span class="p">,</span> <span class="nx">server_config</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="nx">port</span><span class="p">);</span> <span class="p">});</span> <span class="p">}</span> <span class="kd">function</span> <span class="nx">getGroupId</span><span class="p">(</span><span class="nx">roomid</span><span class="p">,</span> <span class="nx">callback</span><span class="p">)</span> <span class="p">{</span> <span class="kd">var</span> <span class="nx">rt</span> <span class="o">=</span> <span class="k">new</span> <span class="nb">Date</span><span class="p">().</span><span class="nx">now</span><span class="p">;</span> <span class="kd">var</span> <span class="nx">devid</span> <span class="o">=</span> <span class="nx">uuid</span><span class="p">.</span><span class="nx">v4</span><span class="p">().</span><span class="nx">replace</span><span class="p">(</span><span class="sr">/-/g</span><span class="p">,</span> <span class="s1">''</span><span class="p">);</span> <span class="kd">var</span> <span class="nx">vk</span> <span class="o">=</span> <span class="nx">md5</span><span class="p">(</span><span class="nx">rt</span> <span class="o">+</span> <span class="s1">'7oE9nPEG9xXV69phU31FYCLUagKeYtsF'</span> <span class="o">+</span> <span class="nx">devid</span><span class="p">)</span> <span class="kd">var</span> <span class="nx">req</span> <span class="o">=</span> <span class="s1">'type@=loginreq/username@=/password@=/roomid@='</span> <span class="o">+</span> <span class="nx">roomid</span> <span class="o">+</span> <span class="s1">'/ct@=0/vk@='</span> <span class="o">+</span> <span class="nx">vk</span> <span class="o">+</span> <span class="s1">'/devid@='</span> <span class="o">+</span> <span class="nx">devid</span> <span class="o">+</span> <span class="s1">'/rt@='</span> <span class="o">+</span> <span class="nx">rt</span> <span class="o">+</span> <span class="s1">'/ver=@20150929/'</span><span class="p">;</span> <span class="nx">getGroupServer</span><span class="p">(</span><span class="nx">roomid</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">server</span><span class="p">,</span> <span class="nx">port</span><span class="p">)</span> <span class="p">{</span> <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s1">'group server: '</span> <span class="o">+</span> <span class="nx">server</span> <span class="o">+</span> <span class="s1">':'</span> <span class="o">+</span> <span class="nx">port</span><span class="p">);</span> <span class="kd">var</span> <span class="nx">socket</span> <span class="o">=</span> <span class="nx">net</span><span class="p">.</span><span class="nx">connect</span><span class="p">(</span><span class="nx">port</span><span class="p">,</span> <span class="nx">server</span><span class="p">,</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span> <span class="nx">send</span><span class="p">(</span><span class="nx">socket</span><span class="p">,</span> <span class="nx">req</span><span class="p">);</span> <span class="p">});</span> <span class="nx">socket</span><span class="p">.</span><span class="nx">on</span><span class="p">(</span><span class="s1">'data'</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">data</span><span class="p">)</span> <span class="p">{</span> <span class="k">if</span> <span class="p">(</span><span class="nx">data</span><span class="p">.</span><span class="nx">indexOf</span><span class="p">(</span><span class="s1">'type@=setmsggroup'</span><span class="p">)</span> <span class="o">>=</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span> <span class="kd">var</span> <span class="nx">gid</span> <span class="o">=</span> <span class="nx">data</span><span class="p">.</span><span class="nx">toString</span><span class="p">().</span><span class="nx">match</span><span class="p">(</span><span class="sr">/gid@=(.*?)\//g</span><span class="p">)[</span><span class="mi">0</span><span class="p">].</span><span class="nx">replace</span><span class="p">(</span><span class="s1">'gid@='</span><span class="p">,</span> <span class="s1">''</span><span class="p">);</span> <span class="nx">gid</span> <span class="o">=</span> <span class="nx">gid</span><span class="p">.</span><span class="nx">substring</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="nx">gid</span><span class="p">.</span><span class="nx">length</span> <span class="o">-</span> <span class="mi">1</span><span class="p">);</span> <span class="nx">socket</span><span class="p">.</span><span class="nx">destroy</span><span class="p">();</span> <span class="nx">callback</span><span class="p">(</span><span class="nx">gid</span><span class="p">);</span> <span class="p">}</span> <span class="p">});</span> <span class="p">});</span> <span class="p">}</span> <span class="kd">function</span> <span class="nx">monitorRoom</span><span class="p">(</span><span class="nx">roomid</span><span class="p">)</span> <span class="p">{</span> <span class="kd">var</span> <span class="nx">socket</span> <span class="o">=</span> <span class="nx">net</span><span class="p">.</span><span class="nx">connect</span><span class="p">(</span><span class="nx">PORT</span><span class="p">,</span> <span class="nx">HOST</span><span class="p">,</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span> <span class="nx">login</span><span class="p">(</span><span class="nx">socket</span><span class="p">,</span> <span class="s1">'visitor1234567'</span><span class="p">,</span> <span class="s1">'1234567890123456'</span><span class="p">);</span> <span class="p">});</span> <span class="nx">setInterval</span><span class="p">(</span><span class="kd">function</span><span class="p">()</span> <span class="p">{</span> <span class="nx">send</span><span class="p">(</span><span class="nx">socket</span><span class="p">,</span> <span class="s1">'type@=keeplive/tick@=70/'</span><span class="p">);</span> <span class="c1">//send keep alive message repeatly</span> <span class="p">},</span> <span class="mi">50000</span><span class="p">);</span> <span class="nx">socket</span><span class="p">.</span><span class="nx">on</span><span class="p">(</span><span class="s1">'data'</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">data</span><span class="p">)</span> <span class="p">{</span> <span class="c1">//data is a Buffer here</span> <span class="k">if</span> <span class="p">(</span><span class="nx">data</span><span class="p">.</span><span class="nx">indexOf</span><span class="p">(</span><span class="s1">'type@=loginres'</span><span class="p">)</span> <span class="o">>=</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span> <span class="nx">getGroupId</span><span class="p">(</span><span class="nx">roomid</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">gid</span><span class="p">)</span> <span class="p">{</span> <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s1">'gid of room['</span> <span class="o">+</span> <span class="nx">roomid</span> <span class="o">+</span><span class="s1">'] is '</span> <span class="o">+</span> <span class="nx">gid</span><span class="p">)</span> <span class="nx">send</span><span class="p">(</span><span class="nx">socket</span><span class="p">,</span> <span class="s1">'type@=joingroup/rid@='</span> <span class="o">+</span> <span class="nx">roomid</span> <span class="o">+</span> <span class="s1">'/gid@='</span> <span class="o">+</span> <span class="nx">gid</span> <span class="o">+</span> <span class="s1">'/'</span><span class="p">);</span> <span class="p">});</span> <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="nx">data</span><span class="p">.</span><span class="nx">indexOf</span><span class="p">(</span><span class="s1">'type@=chatmessage'</span><span class="p">)</span> <span class="o">>=</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span> <span class="kd">var</span> <span class="nx">msg</span> <span class="o">=</span> <span class="nx">data</span><span class="p">.</span><span class="nx">toString</span><span class="p">();</span> <span class="kd">var</span> <span class="nx">snick</span> <span class="o">=</span> <span class="nx">msg</span><span class="p">.</span><span class="nx">match</span><span class="p">(</span><span class="sr">/snick@=(.*?)\//g</span><span class="p">)[</span><span class="mi">0</span><span class="p">].</span><span class="nx">replace</span><span class="p">(</span><span class="s1">'snick@='</span><span class="p">,</span> <span class="s1">''</span><span class="p">);</span> <span class="kd">var</span> <span class="nx">content</span> <span class="o">=</span> <span class="nx">msg</span><span class="p">.</span><span class="nx">match</span><span class="p">(</span><span class="sr">/content@=(.*?)\//g</span><span class="p">)[</span><span class="mi">0</span><span class="p">].</span><span class="nx">replace</span><span class="p">(</span><span class="s1">'content@='</span><span class="p">,</span> <span class="s1">''</span><span class="p">);</span> <span class="nx">snick</span> <span class="o">=</span> <span class="nx">snick</span><span class="p">.</span><span class="nx">substring</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="nx">snick</span><span class="p">.</span><span class="nx">length</span> <span class="o">-</span> <span class="mi">1</span><span class="p">);</span> <span class="nx">content</span> <span class="o">=</span> <span class="nx">content</span><span class="p">.</span><span class="nx">substring</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="nx">content</span><span class="p">.</span><span class="nx">length</span> <span class="o">-</span> <span class="mi">1</span><span class="p">);</span> <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">snick</span> <span class="o">+</span> <span class="s1">': '</span> <span class="o">+</span> <span class="nx">content</span><span class="p">);</span><span class="c1">// 弹幕</span> <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="nx">data</span><span class="p">.</span><span class="nx">indexOf</span><span class="p">(</span><span class="s1">'type@=userenter'</span><span class="p">)</span> <span class="o">>=</span> <span class="mi">0</span> <span class="o">||</span> <span class="nx">data</span><span class="p">.</span><span class="nx">indexOf</span><span class="p">(</span><span class="s1">'type@=keeplive'</span><span class="p">)</span> <span class="o">>=</span> <span class="mi">0</span> <span class="o">||</span> <span class="nx">data</span><span class="p">.</span><span class="nx">indexOf</span><span class="p">(</span><span class="s1">'type@=dgn/gfid@=131'</span><span class="p">)</span> <span class="o">>=</span> <span class="mi">0</span> <span class="o">||</span> <span class="nx">data</span><span class="p">.</span><span class="nx">indexOf</span><span class="p">(</span><span class="s1">'type@=blackres'</span><span class="p">)</span> <span class="o">>=</span> <span class="mi">0</span> <span class="o">||</span> <span class="nx">data</span><span class="p">.</span><span class="nx">indexOf</span><span class="p">(</span><span class="s1">'type@=dgn/gfid@=129'</span><span class="p">)</span> <span class="o">>=</span> <span class="mi">0</span> <span class="o">||</span> <span class="nx">data</span><span class="p">.</span><span class="nx">indexOf</span><span class="p">(</span><span class="s1">'type@=upgrade'</span><span class="p">)</span> <span class="o">>=</span> <span class="mi">0</span> <span class="o">||</span> <span class="nx">data</span><span class="p">.</span><span class="nx">indexOf</span><span class="p">(</span><span class="s1">'type@=ranklist'</span><span class="p">)</span> <span class="o">>=</span> <span class="mi">0</span> <span class="o">||</span> <span class="nx">data</span><span class="p">.</span><span class="nx">indexOf</span><span class="p">(</span><span class="s1">'type@=onlinegift'</span><span class="p">)</span> <span class="o">>=</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span> <span class="c1">//没用的消息</span> <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="nx">data</span><span class="p">.</span><span class="nx">indexOf</span><span class="p">(</span><span class="s1">'type@=spbc'</span><span class="p">)</span> <span class="o">>=</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span> <span class="kd">var</span> <span class="nx">drid</span> <span class="o">=</span> <span class="nx">data</span><span class="p">.</span><span class="nx">toString</span><span class="p">().</span><span class="nx">match</span><span class="p">(</span><span class="sr">/drid@=(.*?)\//g</span><span class="p">)[</span><span class="mi">0</span><span class="p">].</span><span class="nx">replace</span><span class="p">(</span><span class="s1">'drid@='</span><span class="p">,</span> <span class="s1">''</span><span class="p">);</span> <span class="nx">drid</span> <span class="o">=</span> <span class="nx">drid</span><span class="p">.</span><span class="nx">substring</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="nx">drid</span><span class="p">.</span><span class="nx">length</span> <span class="o">-</span> <span class="mi">1</span><span class="p">);</span> <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s1">'rocket! room id:'</span> <span class="o">+</span> <span class="nx">drid</span><span class="p">);</span> <span class="p">}</span> <span class="k">else</span> <span class="p">{</span> <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">data</span><span class="p">.</span><span class="nx">toString</span><span class="p">());</span> <span class="c1">//在这里显示其它类型的消息</span> <span class="p">}</span> <span class="p">});</span> <span class="p">}</span> <span class="nx">monitorRoom</span><span class="p">(</span><span class="s1">'<这里填roomid>'</span><span class="p">);</span>
技术核心我看大家都没答到一点,就是反编译flash播放器,因为所有与socket相关的实现都在flash里,反编译出源码后的逻辑、协议,一目了然,然后用python实现出来,很简单,不上码了。
这问题应该是纯技术交流吧,我这么想。 斗鱼已经开放第三方接口了,获取弹幕的流程变得简单了许多:
《斗鱼弹幕服务器第三方接入协议v1.4.1》发布信息 斗鱼开发者论坛
以下为大概流程
第三方接入弹幕服务器:
IP 地址:http://openbarrage.douyutv.com 端口:8601
1.客户端向服务器端发送登录请求,格式为;
type@=loginreq/roomid@=****/

ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

AI Hentai Generator
AIヘンタイを無料で生成します。

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

SublimeText3 中国語版
中国語版、とても使いやすい

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

ホットトピック











このチュートリアルでは、Pythonを使用してZIPFの法則の統計的概念を処理する方法を示し、法律の処理時にPythonの読み取りおよび並べ替えの効率性を示します。 ZIPF分布という用語が何を意味するのか疑問に思うかもしれません。この用語を理解するには、まずZIPFの法律を定義する必要があります。心配しないでください、私は指示を簡素化しようとします。 ZIPFの法則 ZIPFの法則は単に意味します。大きな自然言語のコーパスでは、最も頻繁に発生する単語は、2番目の頻繁な単語のほぼ2倍の頻度で表示されます。 例を見てみましょう。アメリカ英語の茶色のコーパスを見ると、最も頻繁な言葉は「thであることに気付くでしょう。

ノイズの多い画像を扱うことは、特に携帯電話や低解像度のカメラの写真でよくある問題です。 このチュートリアルでは、OpenCVを使用してPythonの画像フィルタリング手法を調査して、この問題に取り組みます。 画像フィルタリング:強力なツール 画像フィルター

この記事では、Pythonライブラリである美しいスープを使用してHTMLを解析する方法について説明します。 find()、find_all()、select()、およびget_text()などの一般的な方法は、データ抽出、多様なHTML構造とエラーの処理、および代替案(SEL

データサイエンスと処理のお気に入りであるPythonは、高性能コンピューティングのための豊富なエコシステムを提供します。ただし、Pythonの並列プログラミングは、独自の課題を提示します。このチュートリアルでは、これらの課題を調査し、グローバルな承認に焦点を当てています

この記事では、深い学習のためにTensorflowとPytorchを比較しています。 関連する手順、データの準備、モデルの構築、トレーニング、評価、展開について詳しく説明しています。 特に計算グラップに関して、フレームワーク間の重要な違い

このチュートリアルでは、Python 3にカスタムパイプラインデータ構造を作成し、機能を強化するためにクラスとオペレーターのオーバーロードを活用していることを示しています。 パイプラインの柔軟性は、一連の機能をデータセットに適用する能力にあります。

Pythonオブジェクトのシリアル化と脱介入は、非自明のプログラムの重要な側面です。 Pythonファイルに何かを保存すると、構成ファイルを読み取る場合、またはHTTPリクエストに応答する場合、オブジェクトシリアル化と脱滑り化を行います。 ある意味では、シリアル化と脱派化は、世界で最も退屈なものです。これらすべての形式とプロトコルを気にするのは誰ですか? Pythonオブジェクトを維持またはストリーミングし、後で完全に取得したいと考えています。 これは、概念レベルで世界を見るのに最適な方法です。ただし、実用的なレベルでは、選択したシリアル化スキーム、形式、またはプロトコルは、プログラムの速度、セキュリティ、メンテナンスの自由、およびその他の側面を決定する場合があります。

Pythonの統計モジュールは、強力なデータ統計分析機能を提供して、生物統計やビジネス分析などのデータの全体的な特性を迅速に理解できるようにします。データポイントを1つずつ見る代わりに、平均や分散などの統計を見て、無視される可能性のある元のデータの傾向と機能を発見し、大きなデータセットをより簡単かつ効果的に比較してください。 このチュートリアルでは、平均を計算し、データセットの分散の程度を測定する方法を説明します。特に明記しない限り、このモジュールのすべての関数は、単に平均を合計するのではなく、平均()関数の計算をサポートします。 浮動小数点数も使用できます。 ランダムをインポートします インポート統計 fractiから
