Commit 66faa6d8 by zhiwei

添加B站弹幕采集

parent 5bbec004
package com.zhiwei.live.danmu.bilibili;
import java.util.concurrent.TimeUnit;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import com.zhiwei.crawler.core.HttpBoot;
import com.zhiwei.crawler.core.RequestUtils;
import com.zhiwei.live.danmu.util.Connector;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.handler.timeout.IdleStateHandler;
import okhttp3.Request;
import okhttp3.Response;
public class BilibiliClient {
private static HttpBoot httpBoot = new HttpBoot();
public static void main(String[] args) throws InterruptedException {
// String address = "62.234.213.204";
// int port = 2243;
String roomId = "1029";
Request request = RequestUtils.wrapGet("https://live.bilibili.com/api/player?id=cid:" + roomId);
String host = null;
int port = 2243;
try(Response response = httpBoot.syncCall(request)) {
Document doc = Jsoup.parse(response.body().string());
String[] address = doc.select("dm_server_list").text().split(",");
host = address[0];
System.out.println(host);
} catch(Exception e) {
throw new IllegalArgumentException("获取聊天服务器地址失败", e);
}
Connector.asynchronizedTcpConnect(new NioEventLoopGroup(), host, port,
new IdleStateHandler(0, 30, 0,TimeUnit.SECONDS), new BilibiliMessageHandler("1029")).sync();
}
}
package com.zhiwei.live.danmu.bilibili;
import java.util.Date;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
public class BilibiliEntity {
String messageType; //弹幕消息类型
String user_id; //发布者uid
String nickName; //发布者昵称
Date time; //弹幕时间
String content; //弹幕内容
public BilibiliEntity(JSONObject json) throws Exception {
constructJson(json);
}
public BilibiliEntity(){
}
private void constructJson(JSONObject json) throws Exception{
try {
JSONArray jsonArray = json.getJSONArray("info");
messageType = json.getString("cmd");
user_id = jsonArray.getJSONArray(2).getString(0);
time = new Date();
nickName = jsonArray.getJSONArray(2).getString(1);
content = jsonArray.getString(1);
} catch (Exception e) {
throw new Exception();
}
}
@Override
public String toString() {
return "new PandamMessage["
+ "user_id = " + user_id
+ ", nickName = " + nickName
+ ", messageType = " + messageType
+ ", time = " + time
+ ", content = " + content
+ "]";
}
public Date getTime() {
return time;
}
public void setTime(Date time) {
this.time = time;
}
public String getMessageType() {
return messageType;
}
public String getUser_id() {
return user_id;
}
public String getNickName() {
return nickName;
}
public String getContent() {
return content;
}
public void setMessageType(String messageType) {
this.messageType = messageType;
}
public void setUser_id(String user_id) {
this.user_id = user_id;
}
public void setNickName(String nickName) {
this.nickName = nickName;
}
public void setContent(String content) {
this.content = content;
}
}
package com.zhiwei.live.danmu.bilibili;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.commons.lang3.StringUtils;
import com.alibaba.fastjson.JSONObject;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufUtil;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.handler.timeout.IdleState;
import io.netty.handler.timeout.IdleStateEvent;
import io.netty.util.CharsetUtil;
import io.netty.util.ReferenceCountUtil;
public class BilibiliMessageHandler extends ChannelInboundHandlerAdapter{
private static final byte[] FIRST_REQ = new byte[] { 0x00, 0x00, 0x00 };
private static final byte[] BILI_IN = new byte[] { 0x00, 0x10, 0x00 , 0x01, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,0x01};
private static final byte[] PING = new byte[] { 0x00, 0x00, 0x00, 0x1F, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x5B, 0x6F, 0x62, 0x6A, 0x65, 0x63, 0x74, 0x20, 0x4F, 0x62, 0x6A, 0x65, 0x63, 0x74, 0x5D };
private static Pattern pattern = Pattern.compile("\\{\"cmd\":\"DANMU_MSG.+?\\]\\}");
private String roomid;
/**
* Constructor
*
* @param roomId
* 房间号
*/
public BilibiliMessageHandler(String roomid) {
this.roomid = roomid;
}
/*
* @see
* io.netty.channel.ChannelInboundHandlerAdapter#channelActive(io.netty.channel.
* ChannelHandlerContext)
*/
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
System.out.println("TCP 连接建立成功: " + ctx.channel());
byte[] body = StringUtils
.join("{\"uid\":0,\"roomid\":", roomid, ",\"protover\":1,\"platform\":\"web\",\"clientver\":\"1.5.15\"}")
.getBytes();
ByteBuf loginMsg = Unpooled.wrappedBuffer(Unpooled.wrappedBuffer(FIRST_REQ)
,Unpooled.buffer(1).writeByte(body.length+16),Unpooled.wrappedBuffer(BILI_IN), Unpooled.wrappedBuffer(body));
System.out.println("发送登录消息: \n" + ByteBufUtil.prettyHexDump(loginMsg));
ctx.writeAndFlush(loginMsg);
}
/*
* @see
* io.netty.channel.ChannelInboundHandlerAdapter#channelRead(io.netty.channel.
* ChannelHandlerContext, java.lang.Object)
*/
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
if (msg instanceof ByteBuf) {
ByteBuf buf = (ByteBuf) msg;
// System.out.println("收到消息: \n" + ByteBufUtil.prettyHexDump(buf));
String source = buf.toString(CharsetUtil.UTF_8);
Matcher matcher = pattern.matcher(source);
while(matcher.find()) {
JSONObject dataJson = JSONObject.parseObject(matcher.group());
BilibiliEntity bilibiliEntity = new BilibiliEntity(dataJson);
System.out.println(bilibiliEntity.toString());
}
}
ReferenceCountUtil.release(msg);
}
/*
* @see
* io.netty.channel.ChannelInboundHandlerAdapter#userEventTriggered(io.netty.
* channel.ChannelHandlerContext, java.lang.Object)
*/
@Override
public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
if (evt instanceof IdleStateEvent) {
IdleStateEvent event = (IdleStateEvent) evt;
if (event.state() == IdleState.WRITER_IDLE) {
ByteBuf pingMsg = Unpooled.wrappedBuffer(PING);
System.out.println("发送心跳消息: \n" + ByteBufUtil.prettyHexDump(pingMsg));
ctx.writeAndFlush(pingMsg);
} else {
ctx.fireUserEventTriggered(evt);
}
} else {
ctx.fireUserEventTriggered(evt);
}
}
}
......@@ -4,7 +4,7 @@ import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.zhiwei.crawler.core.HttpBoot;
import com.zhiwei.crawler.core.RequestUtils;
import com.zhiwei.live.danmu.pandamtv.util.Connector;
import com.zhiwei.live.danmu.util.Connector;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.handler.timeout.IdleStateHandler;
......
......@@ -6,7 +6,6 @@ import java.util.regex.Pattern;
import org.apache.commons.lang3.StringUtils;
import com.alibaba.fastjson.JSONObject;
import com.zhiwei.live.danmu.pandamtv.entity.PandamMessage;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufUtil;
......
package com.zhiwei.live.danmu.pandamtv.entity;
package com.zhiwei.live.danmu.pandamtv;
import com.alibaba.fastjson.JSONObject;
......
package com.zhiwei.live.danmu.pandamtv.listener;
package com.zhiwei.live.danmu.pandamtv;
import java.util.List;
import java.util.Vector;
import com.zhiwei.live.danmu.pandamtv.entity.PandamMessage;
public class PandamMessageListener extends Thread{
public static List<PandamMessage> messages = new Vector<>();
......
package com.zhiwei.live.danmu.pandamtv.util;
package com.zhiwei.live.danmu.util;
import java.io.IOException;
import java.net.DatagramSocket;
......
package com.zhiwei.live.test.roomInfo;
import org.junit.jupiter.api.Test;
import com.zhiwei.common.config.GroupType;
import com.zhiwei.crawler.proxy.ProxyFactory;
import com.zhiwei.live.bean.RoomInfo;
import com.zhiwei.live.roominfo.BilibiliRoomInfoCrawler;
import com.zhiwei.live.roominfo.DouYuRoomInfoCrawler;
import com.zhiwei.live.roominfo.HuYaRoomInfoCrawler;
import com.zhiwei.live.roominfo.PandamTVRoomInfoCrawler;
public class RoomInfoCrawlerTest {
private static final String registry = "zookeeper://192.168.0.36:2181";
private static final String group = "local";
static {
ProxyFactory.init(registry, group, GroupType.PROVIDER);
}
@Test
public void getBilibiliRoomInfoByRoomId() {
String roomId = "24";
try {
RoomInfo roomInfo = BilibiliRoomInfoCrawler.getRoomInfoByRoomId(roomId);
System.out.println("房间信息:::"+ roomInfo);
} catch (Exception e) {
e.printStackTrace();
}
}
@Test
public void getDouyuRoomInfoByRoomId() {
String roomId = "5723238";
try {
RoomInfo roomInfo = DouYuRoomInfoCrawler.getRoomInfoByRoomId(roomId);
System.out.println("房间信息:::"+ roomInfo);
} catch (Exception e) {
e.printStackTrace();
}
}
@Test
public void getHuYaRoomInfoByRoomId() {
String roomId = "blizzardgame1";
try {
RoomInfo roomInfo = HuYaRoomInfoCrawler.getRoomInfoByRoomId(roomId);
System.out.println("房间信息:::"+ roomInfo);
} catch (Exception e) {
e.printStackTrace();
}
}
@Test
public void getPandamTVRoomInfoByRoomId() {
String roomId = "1564821";
try {
RoomInfo roomInfo = PandamTVRoomInfoCrawler.getRoomInfoByRoomId(roomId);
System.out.println("房间信息:::"+ roomInfo);
} catch (Exception e) {
e.printStackTrace();
}
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment