aardio

chrome扩展嗅探实现某音直播用户采集

2023-04-16  本文已影响0人  LCSan

原理:
1、编写扩展通过debugger api调用cdp接口,实现Network监听,完成websocket消息获取(protubuf格式)。
2、编写本地web服务,接受wss数据,对protubuf数据解析,完成消息采集。

实现:
1、扩展部分参考:https://www.jianshu.com/p/ed982f8c05bf,稍微修改即可;
2、protubuf解析,采用aardio。核心部分是protubuf结构定义;

dyResponse.proto

message Response {
  required int32 id = 1;
  required int32 msgid = 2;
  required int32 flag = 3;
  required int32 nid = 4;
  
  message Option {
    required string key = 1;
    required string value = 2;
  }
  
  repeated Option option = 5;
  
  message Other {
   optional int32 o1 = 1;
   optional int32 o2 = 2;
   optional int32 o3 = 3;
   optional int32 o4 = 4;
   optional int32 o5 = 5;
   optional int32 o6 = 6;
   optional int32 o7 = 7;
   optional int32 o8 = 8;
   optional int32 o9 = 9;
   optional int32 o10 = 10;
   optional int32 o11 = 11;
   optional int32 o12 = 12;
   optional int32 o13 = 13;
   optional int32 o14 = 14;
  }
  
  required Other other = 6;
  required string type = 7;
  required bytes msg = 8;
}

MsgResponse.proto

message MsgResponse {
    repeated Message messages = 1;
    string cursor = 2;
    int64 fetchInterval = 3;
    int64 now = 4;
    string internalExt = 5;
    int32 fetchType = 6;
    map < string, string > routeParams = 7;
    int64 heartbeatDuration = 8;
    bool needAck = 9;
    string pushServer = 10;
}

message Message {
    string method = 1;
    bytes payload = 2;
    int64 msgId = 3;
    int32 msgType = 4;
    int64 offset = 5;
}

message Contributor {
    int64 score = 1;
    User user = 2;
    int64 rank = 3;
    int64 delta = 4;
    bool isHidden = 5;
    string scoreDescription = 6;
    string exactlyScore = 7;
}

message RoomUserSeqMessage {
    Common common = 1;
    repeated Contributor ranks = 2;
    int64 total = 3;
    string popStr = 4;
    repeated Contributor seats = 5;
    int64 popularity = 6;
    int64 totalUser = 7;
    string totalUserStr = 8;
    string totalStr = 9;
    string onlineUserForAnchor = 10;
    string totalPvForAnchor = 11;

}

message Detail {
    Text text = 1;
    int32 textFontSize = 2;
    Image background = 3;
    int32 start = 4;
    int32 duration = 5;
    int32 x = 6;
    int32 y = 7;
    int32 width = 8;
    int32 height = 9;
    int32 shadowDx = 10;
    int32 shadowDy = 11;
    int32 shadowRadius = 12;
    string shadowColor = 13;
    string strokeColor = 14;
    int32 strokeWidth = 15;
}

message TextEffect {
    Detail portrait = 1;
    Detail landscape = 2;
}

message GiftMessage {
    Common common = 1;
    int64 giftId = 2;
    int64 fanTicketCount = 3;
    int64 groupCount = 4;
    int64 repeatCount = 5;
    int64 comboCount = 6;
    User user = 7;
    User toUser = 8;
    int32 repeatEnd = 9;
    TextEffect textEffect = 10;
    int64 groupId = 11;
    int64 incomeTaskgifts = 12;
    int64 roomFanTicketCount = 13;
    GiftIMPriority priority = 14;
    GiftStruct gift = 15;
    string logId = 16;
    int64 sendType = 17;
    PublicAreaCommon publicAreaCommon = 18;
    Text trayDisplayText = 19;
    int64 bannedDisplayEffects = 20;
    GiftTrayInfo trayInfo = 21;
    AssetEffectMixInfo assetEffectMixInfo = 24;

}

message LikeMessage {
    Common common = 1;
    int64 count = 2;
    int64 total = 3;
    int64 color = 4;
    User user = 5;
    string icon = 6;
}

message ChatMessage {
    Common common = 1;
    User user = 2;
    string content = 3;
    bool visibleToSender = 4;
    Image backgroundImage = 5;
    string fullScreenTextColor = 6;
    Image backgroundImageV2 = 7;
    PublicAreaCommon publicAreaCommon = 9;
    Image giftImage = 10;
}

message SocialMessage {
    Common common = 1;
    User user = 2;
    int64 shareType = 3;
    int64 action = 4;
    string shareTarget = 5;
    int64 followCount = 6;
    PublicAreaCommon publicAreaCommon = 7;
}

message EffectConfig {
    int64 type = 1;
    Image icon = 2;
    int64 avatarPos = 3;
    Text text = 4;
    Image textIcon = 5;
    int32 stayTime = 6;
    int64 animAssetId = 7;
    Image badge = 8;
    repeated int64 flexSettingArray = 9;
    Image textIconOverlay = 10;
    Image animatedBadge = 11;
    bool hasSweepLight = 12;
    repeated int64 textFlexSettingArray = 13;
    int64 centerAnimAssetId = 14;
}

message MemberMessage {
    Common common = 1;
    User user = 2;
    int64 memberCount = 3;
    User operator = 4;
    bool isSetToAdmin = 5;
    bool isTopUser = 6;
    int64 rankScore = 7;
    int64 topUserNo = 8;
    int64 enterType = 9;
    int64 action = 10;
    string actionDescription = 11;
    int64 userId = 12;
    EffectConfig effectConfig = 13;
    string popStr = 14;
    EffectConfig enterEffectConfig = 15;
    Image backgroundImage = 16;
    Image backgroundImageV2 = 17;
    Text anchorDisplayText = 18;
    PublicAreaCommon publicAreaCommon = 19;

}

message ControlMessage {
    Common common = 1;
    int32 status = 2;
}

message FansclubMessage {
    Common commonInfo = 1;
    // 升级是1,加入是2
    int32 type = 2;
    string content = 3;
    User user = 4;
}

message CommonTextMessage {
    Common common = 1;
    User user = 2;
}

message Common {
    string method = 1;
    int64 msgId = 2;
    int64 roomId = 3;
    int64 createTime = 4;
    int32 monitor = 5;
    bool isShowMsg = 6;
    string describe = 7;
    Text displayText = 8;
    int64 foldType = 9;
    int64 anchorFoldType = 10;
    int64 priorityScore = 11;
    string logId = 12;
    string msgProcessFilterK = 13;
    string msgProcessFilterV = 14;
    User user = 15;
    Room room = 16;
    int64 anchorFoldTypeV2 = 17;
    int64 processAtSeiTimeMs = 18;
}

message Text {
    string key = 1;
    string defaultPattern = 2;
    TextFormat defaultFormat = 3;
    repeated TextPiece pieces = 4;
}

message Room {
    int64 id = 1;
    string idStr = 2;
    int64 status = 3;
    int64 ownerUserId = 4;
    string title = 5;
    int64 userCount = 6;
    int64 createTime = 7;
    int64 linkmicLayout = 8;
    int64 finishTime = 9;
    RoomExtra extra = 10;
    string dynamicCoverUri = 11;
    map < int64,
    string > dynamicCoverDict = 12;
    int64 lastPingTime = 13;
    int64 liveId = 14;
    int64 streamProvider = 15;
    int64 osType = 16;
    int64 clientVersion = 17;
    bool withLinkmic = 18;
    bool enableRoomPerspective = 19;
    Image cover = 20;
    Image dynamicCover = 21;
    Image dynamicCoverLow = 22;
    string shareUrl = 23;
    string anchorShareText = 24;
    string userShareText = 25;
    int64 streamId = 26;
    string streamIdStr = 27;
    StreamUrl streamUrl = 28;
    int64 mosaicStatus = 29;
    string mosaicTip = 30;
    int64 cellStyle = 31;
    LinkMic linkMic = 32;
    int64 luckymoneyNum = 33;
    repeated Decoration decoList = 34;
    repeated TopFan topFans = 35;
    RoomStats stats = 36;
    string sunDailyIconContent = 37;
    string distance = 38;
    string distanceCity = 39;
    string location = 40;
    string realDistance = 41;
    Image feedRoomLabel = 42;
    string commonLabelList = 43;
    RoomUserAttr livingRoomAttrs = 44;
    repeated int64 adminUserIds = 45;
    User owner = 46;
    string privateInfo = 47;
}

message RoomExtra {}

message RoomStats {}

message RoomUserAttr {}

message StreamUrl {}

message LinkMic {}

message Decoration {}

message TopFan {}

message UserAttr {}

message OwnRoom {}

message AnchorInfo {}

message FollowInfo {
    int64 followingCount = 1;
    int64 followerCount = 2;
    int64 followStatus = 3;
    int64 pushStatus = 4;
    string remarkName = 5;
}

message UserBadge {
    map < int32,Image > icons = 1;
    string title = 2;
}
message FansClubData {
    string clubName = 1;
    int32 level = 2;
    int32 userFansClubStatus = 3;
    UserBadge badge = 4;
    repeated int64 availableGiftIds = 5;
    int64 anchorId = 6;


}
message FansClub {
    FansClubData data = 1;
    map < int32, FansClubData > preferData = 2;


}

message Border {}

message GradeBuffInfo {
    int64 buffLevel = 1;
    int32 status = 2;
    int64 endTime = 3;
    map < int64,
    int64 > statsInfo = 4;
    Image buffBadge = 5;
}
message GradeIcon {
    Image icon = 1;
    int64 iconDiamond = 2;
    int64 level = 3;
    string levelStr = 4;
}
message PayGrade {
    int64 totalDiamondCount = 1;
    Image diamondIcon = 2;
    string name = 3;
    Image icon = 4;
    string nextName = 5;
    int64 level = 6;
    Image nextIcon = 7;
    int64 nextDiamond = 8;
    int64 nowDiamond = 9;
    int64 thisGradeMinDiamond = 10;
    int64 thisGradeMaxDiamond = 11;
    int64 payDiamondBak = 12;
    string gradeDescribe = 13;
    repeated GradeIcon gradeIconList = 14;
    int64 screenChatType = 15;
    Image imIcon = 16;
    Image imIconWithLevel = 17;
    Image liveIcon = 18;
    Image newImIconWithLevel = 19;
    Image newLiveIcon = 20;
    int64 upgradeNeedConsume = 21;
    string nextPrivileges = 22;
    Image background = 23;
    Image backgroundBack = 24;
    int64 score = 25;
    GradeBuffInfo buffInfo = 26;
    string gradeBanner = 1001;
    Image profileDialogBg = 1002;
    Image profileDialogBgBack = 1003;

}

message User {
    int64 id = 1;
    int64 shortId = 2;
    string nickname = 3;
    int32 gender = 4;
    string signature = 5;
    int32 level = 6;
    int64 birthday = 7;
    string telephone = 8;
    Image avatarThumb = 9;
    Image avatarMedium = 10;
    Image avatarLarge = 11;
    bool verified = 12;
    int32 experience = 13;
    string city = 14;
    int32 status = 15;
    int64 createTime = 16;
    int64 modifyTime = 17;
    int32 secret = 18;
    string shareQrcodeUri = 19;
    int32 incomeSharePercent = 20;
    Image badgeImageList = 21;
    FollowInfo followInfo = 22;
    PayGrade payGrade = 23;
    FansClub fansClub = 24;
    Border border = 25;
    string specialId = 26;
    Image avatarBorder = 27;
    Image medal = 28;
    repeated Image realTimeIcons = 29;
    repeated Image newRealTimeIcons = 30;
    int64 topVipNo = 31;
    UserAttr userAttr = 32;
    OwnRoom ownRoom = 33;
    int64 payScore = 34;
    int64 ticketCount = 35;
    AnchorInfo anchorInfo = 36;
    int32 linkMicStats = 37;
    string displayId = 38;


    string f39 = 39;
    string f40 = 40;
    string f41 = 41;
    string f42 = 42;
    string f43 = 43;
    string f44 = 44;
    string f45 = 45;
    string secUid = 46;
    string f47 = 47;
    string f48 = 48;
    string f49 = 49;
    
    string f50 = 50;
    string f51 = 51;
    string f52 = 52;
    string  f53 = 53;
    int32 f54 = 54;
    string f55 = 55;
    string f56 = 56;
    string f57 = 57;
    string f58 = 58;
    string f59 = 59;
    
    string f60 = 60;
    Image f61 = 61;
    string f62 = 62;
    string f63 = 63;
    string f64 = 64;
    string f65 = 65;
    bool f66 = 66;
    string f67 = 67;
    string desc = 68;
    string f69 = 69;
    
    string f70 = 70;
    string f71 = 71;
    string f72 = 72;
    string webCastSecUid = 73;
    string f74 = 74;
    string f75 = 75;
    string f76 = 76;
    string f77 = 77;
    string f78 = 78;
    string f79 = 79;
}

message TextFormat {
    string color = 1;
    bool bold = 2;
    bool italic = 3;
    int32 weight = 4;
    int32 italicAngle = 5;
    int32 fontSize = 6;
    bool userHeightLightColor = 7;
    bool useRemoteClor = 8;
}

message TextPiece {
    int32 type = 1;
    TextFormat format = 2;
    string stringValue = 11;
    TextPieceUser userValue = 21;
}

message Content {
    string name = 1;
    string fontColor = 2;
    int64 level = 3;
    string alternativeText = 4;
}

message Image {
    repeated string urlList = 1;
    string uri = 2;
    int64 height = 3;
    int64 width = 4;
    string avgColor = 5;
    int32 imageType = 6;
    string openWebUrl = 7;
    Content content = 8;
    bool isAnimated = 9;


}

message TextPieceUser {
    User user = 1;
    bool withColon = 2;
}

message PublicAreaCommon {
    Image userLabel = 1;
    int64 userConsumeInRoom = 2;
    int64 userSendGiftCntInRoom = 3;
}

message GiftIMPriority {
    repeated int64 queueSizes = 1;
    int64 selfQueuePriority = 2;
    int64 priority = 3;
}

message GiftTrayInfo {
    Text trayDisplayText = 1;
    Image trayBaseImg = 2;
    Image trayHeadImg = 3;
    Image trayRightImg = 4;
    int64 trayLevel = 5;
    Image trayDynamicImg = 6;
}

message GiftStructFansClubInfo {
    int32 minLevel = 1;
    int32 insertPos = 2;
}

message GiftStruct {
    Image image = 1;
    string describe = 2;
    bool notify = 3;
    int64 duration = 4;
    int64 id = 5;
    GiftStructFansClubInfo fansclubInfo = 6;
    bool forLinkmic = 7;
    bool doodle = 8;
    bool forFansclub = 9;
    bool combo = 10;
    int32 type = 11;
    int32 diamondCount = 12;
    int32 isDisplayedOnPanel = 13;
    int64 primaryEffectId = 14;
    Image giftLabelIcon = 15;
    string name = 16;
    string region = 17;
    string manual = 18;
    bool forCustom = 19;
    map < string,
    int64 > specialEffects = 20;
    Image icon = 21;
    int32 actionType = 22;
    int32 watermelonSeeds = 23;
    string goldEffect = 24;
    repeated LuckyMoneyGiftMeta subs = 25;
    int64 goldenBeans = 26;
    int64 honorLevel = 27;
    int32 itemType = 28;
    string schemeUrl = 29;
    GiftPanelOperation giftOperation = 30;
    string eventName = 31;
    int64 nobleLevel = 32;
    string guideUrl = 33;
    bool punishMedicine = 34;
    bool forPortal = 35;
    string businessText = 36;
    bool cnyGift = 37;
    int64 appId = 38;
    int64 vipLevel = 39;
    bool isGray = 40;
    string graySchemeUrl = 41;
    int64 giftScene = 42;
    GiftBanner giftBanner = 43;
    repeated string triggerWords = 44;
    repeated GiftBuffInfo giftBuffInfos = 45;
    bool forFirstRecharge = 46;
    Image dynamicImgForSelected = 47;
    int32 afterSendAction = 48;
    int64 giftOfflineTime = 49;
    string topBarText = 50;
    Image topRightAvatar = 51;
    string bannerSchemeUrl = 52;
    bool isLocked = 53;
    int64 reqExtraType = 54;
    repeated int64 assetIds = 55;
    GiftPreviewInfo giftPreviewInfo = 56;
    GiftTip giftTip = 57;
    int32 needSweepLightCount = 58;
    repeated GiftGroupInfo groupInfo = 59;


}

message AssetEffectMixInfo {}

message LuckyMoneyGiftMeta {}

message GiftPanelOperation {}

message GiftBanner {}

message GiftBuffInfo {}

message GiftPreviewInfo {}

message GiftTip {}

message GiftGroupInfo {}

message EffectMixImageInfo {}

3、poto结构解析转bean代码

import protobuf.parser;

var par = protobuf.parser(); 
par.parseFile("/res/dyResponse.proto",,false);
par.parseFile("/res/MsgResponse.proto",,false);

4、wss数据解析

// 抖音直播 protobuf 解析
import console;
import protobuf.parser;
import zlib;

/*
var par = protobuf.parser(); 
par.parseFile("/res/dyResponse.proto",,false);
par.parseFile("/res/MsgResponse.proto",,false);
*/

import AnchorInfo;
import AssetEffectMixInfo;
import Border;
import ChatMessage;
import Common;
import config;
import Content;
import Contributor;
import ControlMessage;
import Decoration;
import Detail;
import EffectConfig;
import EffectMixImageInfo;
import FansClub;
import FansClubData;
import FansclubMessage;
import FollowInfo;
import GiftBanner;
import GiftBuffInfo;
import GiftGroupInfo;
import GiftIMPriority;
import GiftMessage;
import GiftPanelOperation;
import GiftPreviewInfo;
import GiftStruct;
import GiftStructFansClubInfo;
import GiftTip;
import GiftTrayInfo;
import GradeBuffInfo;
import GradeIcon;
import Image;
import LikeMessage;
import LinkMic;
import LuckyMoneyGiftMeta;
import MemberMessage;
import Message;
import MsgResponse;
import OwnRoom;
import PayGrade;
import PublicAreaCommon;
import Response;
import Room;
import RoomExtra;
import RoomStats;
import RoomUserAttr;
import RoomUserSeqMessage;
import CommonTextMessage;
import SocialMessage;
import StreamUrl;
import Text;
import TextEffect;
import TextFormat;
import TextPiece;
import TextPieceUser;
import TopFan;
import User;
import UserAttr;
import UserBadge; 

import zlib;
import crypt.bin;
import table;

import DouyinDb;

namespace DouyinLive;


var db = ..DouyinDb.DouyinDb();

function saveDb(data){
    //..console.dumpTable(data);
    db.saveLive(data);
} 

function readRsp(user,roomid){      
    u = null;   
    if(user["id"]){
        u = {
            uid = user["id"] ? ..string.format("%.0f",user.id) : "";
            shortId = user["shortId"] ? ..string.format("%.0f",user.shortId) : "";
            displayId = user["displayId"] ? tostring(user.displayId) : "";
            secUid = user["secUid"] ? tostring(user.secUid) : "";
            nickname = user["nickname"] ? user.nickname : "";
            img = user["avatarThumb"] ? user.avatarThumb.urlList[1].value : "";
            roomId = roomid;
        }       
        //..console.dumpTable(u);       
    }
    return u; 
}       

function parse(data,roomid){
    data = ..crypt.bin.decodeBase64(data);
    var res = ..Response();
    res.parseFromString(data);
    txt = ..zlib.gzUncompress(res.msg,"gzip");
    if(txt == null or #txt == 0){
        return {}; 
    }
    var msg = ..MsgResponse(); 
    msg.parseFromString(txt);
    
    var result = {}; 
    var msgs = {}; 
    
    for(k,v in msg.messages){       
        var msgObj = null;
        select(v.method) {
            case "WebcastRoomUserSeqMessage" {
                msgObj = ..RoomUserSeqMessage();
            }
            case "WebcastGiftMessage" {
                msgObj = ..GiftMessage();
            }
            case "WebcastLikeMessage" {
                msgObj = ..LikeMessage();
            }
            case "WebcastChatMessage" {
                msgObj = ..ChatMessage();
            }
            case "WebcastSocialMessage" {
                msgObj = ..SocialMessage(); 
            }
            case "WebcastMemberMessage" {
                msgObj = ..MemberMessage(); 
            }
            case "WebcastControlMessage" {
                msgObj = ..ControlMessage(); 
            }
            case "WebcastFansclubMessage" {
                msgObj = ..FansclubMessage(); 
            }
            case "WebcastCommonTextMessage" {
                msgObj = ..CommonTextMessage(); 
            }
            else {
            }
        }
        
        if(msgObj){
            msgObj.parseFromString(v.payload);
            var user = null; 
            var msg = null; 
            if(msgObj.common && msgObj.common.displayText){
                if(msgObj.common.displayText.defaultPattern){   
                    var defaultPattern = msgObj.common.displayText.defaultPattern;
                    for(k1,v1 in msgObj.common.displayText.pieces){
                        var str = null;
                        if(v1["userValue"]){
                            user = v1.userValue.user;                       
                            str = user.nickname;
                        }else {
                            str = (v1.stringValue == null) ? "" : v1.stringValue;   
                        }       
                        defaultPattern = ..string.replace(defaultPattern,"{" + (k1-1) + "\:[a-zA-Z]+}",str);                        
                    }   
                    msg = ..string.replace(defaultPattern,"{\d+\:[a-zA-Z]+}","");
                    u = readRsp(user,roomid);
                    if(u){
                        ..table.push(result,u);
                        ..table.push(msgs,msg);
                    }
                }
            }elseif(msgObj.user){   
                user = msgObj.user;
                if(msgObj["content"]){
                    msg = user.nickname + " : " + msgObj.content;
                }       
                u = readRsp(user,roomid);
                if(u){
                    ..table.push(result,u);
                    ..table.push(msgs,msg);
                }
            }elseif(msgObj["ranks"]){
                /*
                // 房间同步信息,先不要
                for(k,v in msgObj.ranks){
                    user = v.user;          
                    u = readRsp(user);
                    if(u){
                        table.push(result,u);
                        table.push(msgs,"房间信息同步");
                    }
                }       */  
            }               
        }   
    }
    if(result && #result>0){
        saveDb(result);
    }   
    return msgs; 
}


/**intellisense()
DouyinLive.parse(.(待解析数据) = 抖音数据解析。\n入参为抖音protobuf数据。
end intellisense**/

非成品代码,核心代码已贴。

上一篇 下一篇

猜你喜欢

热点阅读