时间:2021-07-01 10:21:17 帮助过:141人阅读
-1.如果不想看长文,直接使用.则在安装好Python3或者Ruby2.0以上版本.
#安装Python客户端
pip3 install danmu.fm
# 比如主播的直播间
danmu.fm http://www.douyutv.com/16789
#或者
danmu.fm 16789
#安装Ruby客户端
gem install danmu
#使用
danmu douyu [room_id/url]
#比如
danmu douyu qiuri
danmu douyu http://www.douyutv.com/13861
[多图预警][{"ip":"119.90.49.107","port":"8035"},{"ip":"119.90.49.102","port":"8008"},{"ip":"119.90.49.110","port":"8050"},{"ip":"119.90.49.104","port":"8020"},{"ip":"119.90.49.107","port":"8034"},{"ip":"119.90.49.92","port":"8059"},{"ip":"119.90.49.95","port":"8071"},{"ip":"119.90.49.101","port":"8001"},{"ip":"119.90.49.93","port":"8063"},{"ip":"119.90.49.91","port":"8053"}]
##################20160325更新##########################b'\x81\x00\x00\x00\x81\x00\x00\x00\xb2\x02\x00\x00type@=chatmsg/rid@=9401/uid@=12635840/nn@=\xe8\xb6\x85\xe8\xb6\x8a\xe7\xa5\x9e\xe7\x9a\x84boy/txt@=\xe6\x89\x93\xe8\x84\xb8\xe5\x90\xa7/cid@=20e4e3fe427e410c67c5010000000000/level@=5/\x00'
优雅的获取弹幕和看弹幕: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)
那我说说? 弹幕连接 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/]
我记录了下抓取弹幕的流程,可以参考下。var net = require('net');
var uuid = require('node-uuid');
var md5 = require('md5');
var request = require('request');
var HOST = 'danmu.douyutv.com';
var PORT = 8602;
function send(socket, payload)
{
var data = new Buffer(4 + 4 + 4 + payload.length + 1)
data.writeInt32LE(4 + 4 + payload.length + 1, 0); //length
data.writeInt32LE(4 + 4 + payload.length + 1, 4); //code
data.writeInt32LE(0x000002b1, 8); //magic
data.write(payload, 12); //payload
data.writeInt8(0, 4 + 4 + 4 + payload.length); //end of string
socket.write(data)
}
function login(socket, roomid, user, password)
{
var req = 'type@=loginreq/username@=' + user + '/password@=' + password + '/roomid@=' + roomid;
send(socket, req);
}
function getGroupServer(roomid, callback)
{
request({uri:'http://www.douyutv.com/' + roomid}, function(err, resp, body) {
var server_config = JSON.parse(body.match(/room_args = (.*?)\}\;/g)[0].replace('room_args = ', '').replace(';', ''));
server_config = JSON.parse(unescape(server_config['server_config']));
callback(server_config[0].ip, server_config[0].port);
});
}
function getGroupId(roomid, callback)
{
var rt = new Date().now;
var devid = uuid.v4().replace(/-/g, '');
var vk = md5(rt + '7oE9nPEG9xXV69phU31FYCLUagKeYtsF' + devid)
var req = 'type@=loginreq/username@=/password@=/roomid@=' +
roomid + '/ct@=0/vk@=' + vk + '/devid@=' +
devid + '/rt@=' + rt + '/ver=@20150929/';
getGroupServer(roomid, function(server, port) {
console.log('group server: ' + server + ':' + port);
var socket = net.connect(port, server, function() {
send(socket, req);
});
socket.on('data', function(data) {
if (data.indexOf('type@=setmsggroup') >= 0) {
var gid = data.toString().match(/gid@=(.*?)\//g)[0].replace('gid@=', '');
gid = gid.substring(0, gid.length - 1);
socket.destroy();
callback(gid);
}
});
});
}
function monitorRoom(roomid)
{
var socket = net.connect(PORT, HOST, function() {
login(socket, 'visitor1234567', '1234567890123456');
});
setInterval(function() {
send(socket, 'type@=keeplive/tick@=70/'); //send keep alive message repeatly
}, 50000);
socket.on('data', function(data) {
//data is a Buffer here
if (data.indexOf('type@=loginres') >= 0) {
getGroupId(roomid, function(gid) {
console.log('gid of room[' + roomid +'] is ' + gid)
send(socket, 'type@=joingroup/rid@=' + roomid + '/gid@=' + gid + '/');
});
} else if (data.indexOf('type@=chatmessage') >= 0) {
var msg = data.toString();
var snick = msg.match(/snick@=(.*?)\//g)[0].replace('snick@=', '');
var content = msg.match(/content@=(.*?)\//g)[0].replace('content@=', '');
snick = snick.substring(0, snick.length - 1);
content = content.substring(0, content.length - 1);
console.log(snick + ': ' + content);// 弹幕
} else if (data.indexOf('type@=userenter') >= 0 ||
data.indexOf('type@=keeplive') >= 0 ||
data.indexOf('type@=dgn/gfid@=131') >= 0 ||
data.indexOf('type@=blackres') >= 0 ||
data.indexOf('type@=dgn/gfid@=129') >= 0 ||
data.indexOf('type@=upgrade') >= 0 ||
data.indexOf('type@=ranklist') >= 0 ||
data.indexOf('type@=onlinegift') >= 0) {
//没用的消息
} else if (data.indexOf('type@=spbc') >= 0) {
var drid = data.toString().match(/drid@=(.*?)\//g)[0].replace('drid@=', '');
drid = drid.substring(0, drid.length - 1);
console.log('rocket! room id:' + drid);
} else {
console.log(data.toString()); //在这里显示其它类型的消息
}
});
}
monitorRoom('<这里填roomid>');
以前我们是做视频聊天站的。2014年8月-9月我们一个月的时间抄了一个斗鱼,没错是整个站。开始的时候由于内容上的高度重合,比如蜡笔小新、RM等,房间也没有人气,我将斗鱼某房间的弹幕扒下来转播到对应内容的房间中,并过滤掉一些关键字,足以以假乱真。虽然平台最终半死不活,且『技术本身并不可耻』,然而还是匿了。type@=loginreq/roomid@=****/