commit 75c04530a41345b23e3b3d506633f494bb43346d Author: 3202307908 <3202307908@qq.com> Date: Sat May 10 18:32:17 2025 +0800 上传文件至 / diff --git a/__init__.py b/__init__.py new file mode 100644 index 0000000..06d7405 Binary files /dev/null and b/__init__.py differ diff --git a/douyin.cpython-310.pyc b/douyin.cpython-310.pyc new file mode 100644 index 0000000..6676c89 Binary files /dev/null and b/douyin.cpython-310.pyc differ diff --git a/douyin.proto b/douyin.proto new file mode 100644 index 0000000..a922c49 --- /dev/null +++ b/douyin.proto @@ -0,0 +1,745 @@ +syntax = "proto3"; +package douyin; + +message Response { + repeated Message messagesList = 1; + string cursor = 2; + uint64 fetchInterval = 3; + uint64 now = 4; + string internalExt = 5; + uint32 fetchType = 6; + map routeParams = 7; + uint64 heartbeatDuration = 8; + bool needAck = 9; + string pushServer = 10; + string liveCursor = 11; + bool historyNoMore = 12; +} + +message Message{ + string method = 1; + bytes payload = 2; + int64 msgId = 3; + int32 msgType = 4; + int64 offset = 5; + bool needWrdsStore = 6; + int64 wrdsVersion = 7; + string wrdsSubKey = 8; +} + +message EmojiChatMessage { + Common common = 1; + User user = 2; + int64 emojiId = 3; + Text emojiContent = 4; + string defaultContent = 5; + Image backgroundImage = 6; + bool fromIntercom = 7; + bool intercomHideUserCard = 8; +} + +// 聊天 +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; + uint64 agreeMsgId = 11; + uint32 priorityLevel = 12; + LandscapeAreaCommon landscapeAreaCommon = 13; + uint64 eventTime = 15; + bool sendReview = 16; + bool fromIntercom = 17; + bool intercomHideUserCard = 18; + // repeated chatTagsList = 19; + string chatBy = 20; + uint32 individualChatPriority = 21; + Text rtfContent = 22; +} + + +message LandscapeAreaCommon { + bool showHead = 1; + bool showNickname = 2; + bool showFontColor = 3; + repeated string colorValueList = 4; + repeated CommentTypeTag commentTypeTagsList = 5; +} + +message RoomUserSeqMessage { + Common common = 1; + repeated RoomUserSeqMessageContributor ranksList = 2; + int64 total = 3; + string popStr = 4; + repeated RoomUserSeqMessageContributor seatsList = 5; + int64 popularity = 6; + int64 totalUser = 7; + string totalUserStr = 8; + string totalStr = 9; + string onlineUserForAnchor = 10; + string totalPvForAnchor = 11; + string upRightStatsStr = 12; + string upRightStatsStrComplete = 13; + +} + +message CommonTextMessage { + Common common = 1; + User user = 2; + string scene = 3; +} + +message UpdateFanTicketMessage { + Common common = 1; + string roomFanTicketCountText = 2; + uint64 roomFanTicketCount = 3; + bool forceUpdate = 4; +} + +message RoomUserSeqMessageContributor { + uint64 score = 1; + User user = 2; + uint64 rank = 3; + uint64 delta = 4; + bool isHidden = 5; + string scoreDescription = 6; + string exactlyScore = 7; +} + +// 礼物消息 +message GiftMessage { + Common common = 1; + uint64 giftId = 2; + uint64 fanTicketCount = 3; + uint64 groupCount = 4; + uint64 repeatCount = 5; + uint64 comboCount = 6; + User user = 7; + User toUser = 8; + uint32 repeatEnd = 9; + TextEffect textEffect = 10; + uint64 groupId = 11; + uint64 incomeTaskgifts = 12; + uint64 roomFanTicketCount = 13; + GiftIMPriority priority = 14; + GiftStruct gift = 15; + string logId = 16; + uint64 sendType = 17; + PublicAreaCommon publicAreaCommon = 18; + Text trayDisplayText = 19; + uint64 bannedDisplayEffects = 20; + // GiftTrayInfo trayInfo = 21; + // AssetEffectMixInfo assetEffectMixInfo = 22; + bool displayForSelf = 25; + string interactGiftInfo = 26; + string diyItemInfo = 27; + repeated uint64 minAssetSetList = 28; + uint64 totalCount = 29; + uint32 clientGiftSource = 30; + // AnchorGiftData anchorGift = 31; + repeated uint64 toUserIdsList = 32; + uint64 sendTime = 33; + uint64 forceDisplayEffects = 34; + string traceId = 35; + uint64 effectDisplayTs = 36; +} + +message GiftStruct { + Image image = 1; + string describe = 2; + bool notify = 3; + uint64 duration = 4; + uint64 id = 5; + // GiftStructFansClubInfo fansclubInfo = 6; + bool forLinkmic = 7; + bool doodle = 8; + bool forFansclub = 9; + bool combo = 10; + uint32 type = 11; + uint32 diamondCount = 12; + bool isDisplayedOnPanel = 13; + uint64 primaryEffectId = 14; + Image giftLabelIcon = 15; + string name = 16; + string region = 17; + string manual = 18; + bool forCustom = 19; + // specialEffectsMap = 20; + Image icon = 21; + uint32 actionType = 22; + // fixme 后面的就不写了还有几十个属性 + +} + +message GiftIMPriority { + repeated uint64 queueSizesList = 1; + uint64 selfQueuePriority = 2; + uint64 priority = 3; +} + +message TextEffect { + TextEffectDetail portrait = 1; + TextEffectDetail landscape = 2; +} + +message TextEffectDetail { + Text text = 1; + uint32 textFontSize = 2; + Image background = 3; + uint32 start = 4; + uint32 duration = 5; + uint32 x = 6; + uint32 y = 7; + uint32 width = 8; + uint32 height = 9; + uint32 shadowDx = 10; + uint32 shadowDy = 11; + uint32 shadowRadius = 12; + string shadowColor = 13; + string strokeColor = 14; + uint32 strokeWidth = 15; +} + +// 成员消息 +message MemberMessage { + Common common = 1; + User user = 2; + uint64 memberCount = 3; + User operator = 4; + bool isSetToAdmin = 5; + bool isTopUser = 6; + uint64 rankScore = 7; + uint64 topUserNo = 8; + uint64 enterType = 9; + uint64 action = 10; + string actionDescription = 11; + uint64 userId = 12; + EffectConfig effectConfig = 13; + string popStr = 14; + EffectConfig enterEffectConfig = 15; + Image backgroundImage = 16; + Image backgroundImageV2 = 17; + Text anchorDisplayText = 18; + PublicAreaCommon publicAreaCommon = 19; + uint64 userEnterTipType = 20; + uint64 anchorEnterTipType = 21; +} + + +message PublicAreaCommon { + Image userLabel = 1; + uint64 userConsumeInRoom = 2; + uint64 userSendGiftCntInRoom = 3; +} + +message EffectConfig { + uint64 type = 1; + Image icon = 2; + uint64 avatarPos = 3; + Text text = 4; + Image textIcon = 5; + uint32 stayTime = 6; + uint64 animAssetId = 7; + Image badge = 8; + repeated uint64 flexSettingArrayList = 9; + Image textIconOverlay = 10; + Image animatedBadge = 11; + bool hasSweepLight = 12; + repeated uint64 textFlexSettingArrayList = 13; + uint64 centerAnimAssetId = 14; + Image dynamicImage = 15; + map extraMap = 16; + uint64 mp4AnimAssetId = 17; + uint64 priority = 18; + uint64 maxWaitTime = 19; + string dressId = 20; + uint64 alignment = 21; + uint64 alignmentOffset = 22; +} + +message Text { + string key = 1; + string defaultPatter = 2; + TextFormat defaultFormat = 3; + repeated TextPiece piecesList = 4; +} + +message TextPiece { + bool type = 1; + TextFormat format = 2; + string stringValue = 3; + TextPieceUser userValue = 4; + TextPieceGift giftValue = 5; + TextPieceHeart heartValue = 6; + TextPiecePatternRef patternRefValue = 7; + TextPieceImage imageValue = 8; +} + + +message TextPieceImage { + Image image = 1; + float scalingRate = 2; +} + +message TextPiecePatternRef { + string key = 1; + string defaultPattern = 2; +} + +message TextPieceHeart { + string color = 1; +} + +message TextPieceGift { + uint64 giftId = 1; + PatternRef nameRef = 2; +} + +message PatternRef { + string key = 1; + string defaultPattern = 2; +} + +message TextPieceUser { + User user = 1; + bool withColon = 2; +} + +message TextFormat { + string color = 1; + bool bold = 2; + bool italic = 3; + uint32 weight = 4; + uint32 italicAngle = 5; + uint32 fontSize = 6; + bool useHeighLightColor = 7; + bool useRemoteClor = 8; +} + +// 点赞 +message LikeMessage { + Common common = 1; + uint64 count = 2; + uint64 total = 3; + uint64 color = 4; + User user = 5; + string icon = 6; + DoubleLikeDetail doubleLikeDetail = 7; + DisplayControlInfo displayControlInfo = 8; + uint64 linkmicGuestUid = 9; + string scene = 10; + PicoDisplayInfo picoDisplayInfo = 11; +} + +message SocialMessage { + Common common = 1; + User user = 2; + uint64 shareType = 3; + uint64 action = 4; + string shareTarget = 5; + uint64 followCount = 6; + PublicAreaCommon publicAreaCommon = 7; +} + +message PicoDisplayInfo { + uint64 comboSumCount = 1; + string emoji = 2; + Image emojiIcon = 3; + string emojiText = 4; +} + +message DoubleLikeDetail { + bool doubleFlag = 1; + uint32 seqId = 2; + uint32 renewalsNum = 3; + uint32 triggersNum = 4; +} + +message DisplayControlInfo { + bool showText = 1; + bool showIcons = 2; +} + +message EpisodeChatMessage { + Message common = 1; + User user = 2; + string content = 3; + bool visibleToSende = 4; + // BackgroundImage backgroundImage = 5; + // PublicAreaCommon publicAreaCommon = 6; + Image giftImage = 7; + uint64 agreeMsgId = 8; + repeated string colorValueList = 9; +} + + +message MatchAgainstScoreMessage { + Common common = 1; + Against against = 2; + uint32 matchStatus = 3; + uint32 displayStatus = 4; +} + +message Against { + string leftName = 1; + Image leftLogo = 2; + string leftGoal = 3; + // LeftPlayersList leftPlayersList = 4; + // LeftGoalStageDetail leftGoalStageDetail = 5; + string rightName = 6; + Image rightLogo = 7; + string rightGoal = 8; + // RightPlayersList rightPlayersList = 9; + // RightGoalStageDetail rightGoalStageDetail = 10; + uint64 timestamp = 11; + uint64 version = 12; + uint64 leftTeamId = 13; + uint64 rightTeamId = 14; + uint64 diffSei2absSecond = 15; + uint32 finalGoalStage = 16; + uint32 currentGoalStage = 17; + uint32 leftScoreAddition = 18; + uint32 rightScoreAddition = 19; + uint64 leftGoalInt = 20; + uint64 rightGoalInt = 21; +} + +message Common { + string method = 1; + uint64 msgId = 2; + uint64 roomId = 3; + uint64 createTime = 4; + uint32 monitor = 5; + bool isShowMsg = 6; + string describe = 7; + // DisplayText displayText = 8; + uint64 foldType = 9; + uint64 anchorFoldType = 10; + uint64 priorityScore = 11; + string logId = 12; + string msgProcessFilterK = 13; + string msgProcessFilterV = 14; + User user = 15; + // Room room = 16; + uint64 anchorFoldTypeV2 = 17; + uint64 processAtSeiTimeMs = 18; + uint64 randomDispatchMs = 19; + bool isDispatch = 20; + uint64 channelId = 21; + uint64 diffSei2absSecond = 22; + uint64 anchorFoldDuration = 23; +} + +message User { + uint64 id = 1; + uint64 shortId = 2; + string nickName = 3; + uint32 gender = 4; + string Signature = 5; + uint32 Level = 6; + uint64 Birthday = 7; + string Telephone = 8; + Image AvatarThumb = 9; + Image AvatarMedium = 10; + Image AvatarLarge = 11; + bool Verified = 12; + uint32 Experience = 13; + string city = 14; + int32 Status = 15; + uint64 CreateTime = 16; + uint64 ModifyTime = 17; + uint32 Secret = 18; + string ShareQrcodeUri = 19; + uint32 IncomeSharePercent = 20; + repeated 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 RealTimeIconsList = 29; + string displayId = 38; + string secUid = 46; + uint64 fanTicketCount = 1022; + string idStr = 1028; + uint32 ageRange = 1045; + + +} + +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 FansClub{ + FansClubData data = 1; + map preferData = 2; +} +message FansClubData { + string clubName = 1; + int32 level = 2; + int32 userFansClubStatus = 3; + UserBadge badge = 4; + repeated int64 availableGiftIds = 5; + int64 anchorId = 6; +} +message UserBadge { + map icons = 1; + string title = 2; +} + +message GradeBuffInfo { +} + +message Border{ + +} + +message GradeIcon{ + Image icon = 1; + int64 iconDiamond = 2; + int64 level = 3; + string levelStr = 4; +} + +message FollowInfo { + uint64 followingCount = 1; + uint64 followerCount = 2; + uint64 followStatus = 3; + uint64 pushStatus = 4; + string remarkName = 5; + string followerCountStr = 6; + string followingCountStr = 7; + +} +message Image { + repeated string urlListList = 1; + string uri = 2; + uint64 height = 3; + uint64 width = 4; + string avgColor = 5; + uint32 imageType = 6; + string openWebUrl = 7; + ImageContent content = 8; + bool isAnimated = 9; + NinePatchSetting FlexSettingList = 10; + NinePatchSetting TextSettingList = 11; +} + +message NinePatchSetting { + repeated string settingListList = 1; +} + +message ImageContent { + string name = 1; + string fontColor = 2; + uint64 level = 3; + string alternativeText = 4; +} + +message PushFrame { + uint64 seqId = 1; + uint64 logId = 2; + uint64 service = 3; + uint64 method = 4; + repeated HeadersList headersList = 5; + string payloadEncoding = 6; + string payloadType = 7; + bytes payload = 8; +} + +message kk { + uint32 k = 14; +} + +message SendMessageBody { + string conversationId = 1; + uint32 conversationType = 2; + uint64 conversationShortId = 3; + string content = 4; + repeated ExtList ext = 5; + uint32 messageType = 6; + string ticket = 7; + string clientMessageId = 8; +} + +message ExtList { + string key = 1; + string value = 2; +} + +message Rsp{ + int32 a = 1; + int32 b = 2; + int32 c = 3; + string d = 4; + int32 e = 5; + message F { + uint64 q1 = 1; + uint64 q3 = 3; + string q4 = 4; + uint64 q5 = 5; + } + F f = 6; + string g = 7; + uint64 h = 10; + uint64 i = 11; + uint64 j = 13; +} + +message PreMessage { + uint32 cmd = 1; + uint32 sequenceId = 2; + string sdkVersion = 3; + string token = 4; + uint32 refer = 5; + uint32 inboxType = 6; + string buildNumber = 7; + SendMessageBody sendMessageBody = 8; + // 字段名待定 + string aa = 9; + string devicePlatform = 11; + repeated HeadersList headers = 15; + uint32 authType = 18; + string biz = 21; + string access = 22; +} + +message HeadersList { + string key = 1; + string value = 2; +} + +message LiveShoppingMessage { + Common common = 1; + int32 msgType = 2; + int64 promotionId = 4; +} + +message RoomStatsMessage { + Common common = 1; + string displayShort = 2; + string displayMiddle = 3; + string displayLong = 4; + int64 displayValue = 5; + int64 displayVersion = 6; + bool incremental = 7; + bool isHidden = 8; + int64 total = 9; + int64 displayType = 10; +} + +enum CommentTypeTag { + COMMENTTYPETAGUNKNOWN = 0; + COMMENTTYPETAGSTAR = 1; +} + +message ProductInfo { + int64 promotionId = 1; + int32 index = 2; + repeated int64 targetFlashUidsList = 3; + int64 explainType = 4; +} +message CategoryInfo { + int32 id = 1; + string name = 2; + repeated int64 promotionIdsList = 3; + string type = 4; + string uniqueIndex = 5; +} + +message ProductChangeMessage { + Common common = 1; + int64 updateTimestamp = 2; + string updateToast = 3; + repeated ProductInfo updateProductInfoList = 4; + int64 total = 5; + repeated CategoryInfo updateCategoryInfoList = 8; +} + +// from https://github.com/HaoDong108/DouyinBarrageGrab/blob/main/BarrageGrab/proto/message.proto +// status = 3 下播 +message ControlMessage { + Common common = 1; + int32 status = 2; +} + +// from https://github.com/HaoDong108/DouyinBarrageGrab/blob/main/BarrageGrab/proto/message.proto +message FansclubMessage { + Common commonInfo = 1; + // 升级是1,加入是2 + int32 type = 2; + string content = 3; + User user = 4; +} + +// from https://github.com/scx567888/live-room-watcher/blob/master/src/main/proto/douyin_hack/webcast/im/RoomRankMessage.proto +// 直播间排行榜 +message RoomRankMessage { + Common common = 1; + repeated RoomRank ranksList = 2; + + message RoomRank{ + User user = 1; + string scoreStr = 2; + bool profileHidden = 3; + } +} +// from https://github.com/scx567888/live-room-watcher/blob/master/src/main/proto/douyin_hack/webcast/im/RoomMsgTypeEnum.proto +enum RoomMsgTypeEnum{ + DEFAULTROOMMSG = 0; + ECOMLIVEREPLAYSAVEROOMMSG = 1; + CONSUMERRELATIONROOMMSG = 2; + JUMANJIDATAAUTHNOTIFYMSG = 3; + VSWELCOMEMSG = 4; + MINORREFUNDMSG = 5; + PAIDLIVEROOMNOTIFYANCHORMSG = 6; + HOSTTEAMSYSTEMMSG = 7; +} +// from https://github.com/scx567888/live-room-watcher/blob/master/src/main/proto/douyin_hack/webcast/im/RoomMessage.proto +message RoomMessage{ + Common common = 1; + string content = 2; + bool supprotLandscape = 3; + RoomMsgTypeEnum roommessagetype = 4; + bool systemTopMsg = 5; + bool forcedGuarantee = 6; + string bizScene = 20; + map buriedPointMap = 30; +} + diff --git a/douyin.py b/douyin.py new file mode 100644 index 0000000..160c2a3 --- /dev/null +++ b/douyin.py @@ -0,0 +1,844 @@ +# Generated by the protocol buffer compiler. DO NOT EDIT! +# -*- coding: gbk -*- +# sources: douyin.proto +# plugin: python-betterproto +from dataclasses import dataclass +from typing import Dict, List + +import betterproto + + +class CommentTypeTag(betterproto.Enum): + COMMENTTYPETAGUNKNOWN = 0 + COMMENTTYPETAGSTAR = 1 + + +class RoomMsgTypeEnum(betterproto.Enum): + """ + from https://github.com/scx567888/live-room-watcher/blob/master/src/main/pr + oto/douyin_hack/webcast/im/RoomMsgTypeEnum.proto + """ + + DEFAULTROOMMSG = 0 + ECOMLIVEREPLAYSAVEROOMMSG = 1 + CONSUMERRELATIONROOMMSG = 2 + JUMANJIDATAAUTHNOTIFYMSG = 3 + VSWELCOMEMSG = 4 + MINORREFUNDMSG = 5 + PAIDLIVEROOMNOTIFYANCHORMSG = 6 + HOSTTEAMSYSTEMMSG = 7 + + +@dataclass +class Response(betterproto.Message): + messages_list: List["Message"] = betterproto.message_field(1) + cursor: str = betterproto.string_field(2) + fetch_interval: int = betterproto.uint64_field(3) + now: int = betterproto.uint64_field(4) + internal_ext: str = betterproto.string_field(5) + fetch_type: int = betterproto.uint32_field(6) + route_params: Dict[str, str] = betterproto.map_field( + 7, betterproto.TYPE_STRING, betterproto.TYPE_STRING + ) + heartbeat_duration: int = betterproto.uint64_field(8) + need_ack: bool = betterproto.bool_field(9) + push_server: str = betterproto.string_field(10) + live_cursor: str = betterproto.string_field(11) + history_no_more: bool = betterproto.bool_field(12) + + +@dataclass +class Message(betterproto.Message): + method: str = betterproto.string_field(1) + payload: bytes = betterproto.bytes_field(2) + msg_id: int = betterproto.int64_field(3) + msg_type: int = betterproto.int32_field(4) + offset: int = betterproto.int64_field(5) + need_wrds_store: bool = betterproto.bool_field(6) + wrds_version: int = betterproto.int64_field(7) + wrds_sub_key: str = betterproto.string_field(8) + + +@dataclass +class EmojiChatMessage(betterproto.Message): + common: "Common" = betterproto.message_field(1) + user: "User" = betterproto.message_field(2) + emoji_id: int = betterproto.int64_field(3) + emoji_content: "Text" = betterproto.message_field(4) + default_content: str = betterproto.string_field(5) + background_image: "Image" = betterproto.message_field(6) + from_intercom: bool = betterproto.bool_field(7) + intercom_hide_user_card: bool = betterproto.bool_field(8) + + +@dataclass +class ChatMessage(betterproto.Message): + """""" + + common: "Common" = betterproto.message_field(1) + user: "User" = betterproto.message_field(2) + content: str = betterproto.string_field(3) + visible_to_sender: bool = betterproto.bool_field(4) + background_image: "Image" = betterproto.message_field(5) + full_screen_text_color: str = betterproto.string_field(6) + background_image_v2: "Image" = betterproto.message_field(7) + public_area_common: "PublicAreaCommon" = betterproto.message_field(9) + gift_image: "Image" = betterproto.message_field(10) + agree_msg_id: int = betterproto.uint64_field(11) + priority_level: int = betterproto.uint32_field(12) + landscape_area_common: "LandscapeAreaCommon" = betterproto.message_field(13) + event_time: int = betterproto.uint64_field(15) + send_review: bool = betterproto.bool_field(16) + from_intercom: bool = betterproto.bool_field(17) + intercom_hide_user_card: bool = betterproto.bool_field(18) + # repeated chatTagsList = 19; + chat_by: str = betterproto.string_field(20) + individual_chat_priority: int = betterproto.uint32_field(21) + rtf_content: "Text" = betterproto.message_field(22) + + +@dataclass +class LandscapeAreaCommon(betterproto.Message): + show_head: bool = betterproto.bool_field(1) + show_nickname: bool = betterproto.bool_field(2) + show_font_color: bool = betterproto.bool_field(3) + color_value_list: List[str] = betterproto.string_field(4) + comment_type_tags_list: List["CommentTypeTag"] = betterproto.enum_field(5) + + +@dataclass +class RoomUserSeqMessage(betterproto.Message): + common: "Common" = betterproto.message_field(1) + ranks_list: List["RoomUserSeqMessageContributor"] = betterproto.message_field(2) + total: int = betterproto.int64_field(3) + pop_str: str = betterproto.string_field(4) + seats_list: List["RoomUserSeqMessageContributor"] = betterproto.message_field(5) + popularity: int = betterproto.int64_field(6) + total_user: int = betterproto.int64_field(7) + total_user_str: str = betterproto.string_field(8) + total_str: str = betterproto.string_field(9) + online_user_for_anchor: str = betterproto.string_field(10) + total_pv_for_anchor: str = betterproto.string_field(11) + up_right_stats_str: str = betterproto.string_field(12) + up_right_stats_str_complete: str = betterproto.string_field(13) + + +@dataclass +class CommonTextMessage(betterproto.Message): + common: "Common" = betterproto.message_field(1) + user: "User" = betterproto.message_field(2) + scene: str = betterproto.string_field(3) + + +@dataclass +class UpdateFanTicketMessage(betterproto.Message): + common: "Common" = betterproto.message_field(1) + room_fan_ticket_count_text: str = betterproto.string_field(2) + room_fan_ticket_count: int = betterproto.uint64_field(3) + force_update: bool = betterproto.bool_field(4) + + +@dataclass +class RoomUserSeqMessageContributor(betterproto.Message): + score: int = betterproto.uint64_field(1) + user: "User" = betterproto.message_field(2) + rank: int = betterproto.uint64_field(3) + delta: int = betterproto.uint64_field(4) + is_hidden: bool = betterproto.bool_field(5) + score_description: str = betterproto.string_field(6) + exactly_score: str = betterproto.string_field(7) + + +@dataclass +class GiftMessage(betterproto.Message): + """Ϣ""" + + common: "Common" = betterproto.message_field(1) + gift_id: int = betterproto.uint64_field(2) + fan_ticket_count: int = betterproto.uint64_field(3) + group_count: int = betterproto.uint64_field(4) + repeat_count: int = betterproto.uint64_field(5) + combo_count: int = betterproto.uint64_field(6) + user: "User" = betterproto.message_field(7) + to_user: "User" = betterproto.message_field(8) + repeat_end: int = betterproto.uint32_field(9) + text_effect: "TextEffect" = betterproto.message_field(10) + group_id: int = betterproto.uint64_field(11) + income_taskgifts: int = betterproto.uint64_field(12) + room_fan_ticket_count: int = betterproto.uint64_field(13) + priority: "GiftIMPriority" = betterproto.message_field(14) + gift: "GiftStruct" = betterproto.message_field(15) + log_id: str = betterproto.string_field(16) + send_type: int = betterproto.uint64_field(17) + public_area_common: "PublicAreaCommon" = betterproto.message_field(18) + tray_display_text: "Text" = betterproto.message_field(19) + banned_display_effects: int = betterproto.uint64_field(20) + # GiftTrayInfo trayInfo = 21; AssetEffectMixInfo assetEffectMixInfo = 22; + display_for_self: bool = betterproto.bool_field(25) + interact_gift_info: str = betterproto.string_field(26) + diy_item_info: str = betterproto.string_field(27) + min_asset_set_list: List[int] = betterproto.uint64_field(28) + total_count: int = betterproto.uint64_field(29) + client_gift_source: int = betterproto.uint32_field(30) + # AnchorGiftData anchorGift = 31; + to_user_ids_list: List[int] = betterproto.uint64_field(32) + send_time: int = betterproto.uint64_field(33) + force_display_effects: int = betterproto.uint64_field(34) + trace_id: str = betterproto.string_field(35) + effect_display_ts: int = betterproto.uint64_field(36) + + +@dataclass +class GiftStruct(betterproto.Message): + image: "Image" = betterproto.message_field(1) + describe: str = betterproto.string_field(2) + notify: bool = betterproto.bool_field(3) + duration: int = betterproto.uint64_field(4) + id: int = betterproto.uint64_field(5) + # GiftStructFansClubInfo fansclubInfo = 6; + for_linkmic: bool = betterproto.bool_field(7) + doodle: bool = betterproto.bool_field(8) + for_fansclub: bool = betterproto.bool_field(9) + combo: bool = betterproto.bool_field(10) + type: int = betterproto.uint32_field(11) + diamond_count: int = betterproto.uint32_field(12) + is_displayed_on_panel: bool = betterproto.bool_field(13) + primary_effect_id: int = betterproto.uint64_field(14) + gift_label_icon: "Image" = betterproto.message_field(15) + name: str = betterproto.string_field(16) + region: str = betterproto.string_field(17) + manual: str = betterproto.string_field(18) + for_custom: bool = betterproto.bool_field(19) + # specialEffectsMap = 20; + icon: "Image" = betterproto.message_field(21) + action_type: int = betterproto.uint32_field(22) + + +@dataclass +class GiftIMPriority(betterproto.Message): + queue_sizes_list: List[int] = betterproto.uint64_field(1) + self_queue_priority: int = betterproto.uint64_field(2) + priority: int = betterproto.uint64_field(3) + + +@dataclass +class TextEffect(betterproto.Message): + portrait: "TextEffectDetail" = betterproto.message_field(1) + landscape: "TextEffectDetail" = betterproto.message_field(2) + + +@dataclass +class TextEffectDetail(betterproto.Message): + text: "Text" = betterproto.message_field(1) + text_font_size: int = betterproto.uint32_field(2) + background: "Image" = betterproto.message_field(3) + start: int = betterproto.uint32_field(4) + duration: int = betterproto.uint32_field(5) + x: int = betterproto.uint32_field(6) + y: int = betterproto.uint32_field(7) + width: int = betterproto.uint32_field(8) + height: int = betterproto.uint32_field(9) + shadow_dx: int = betterproto.uint32_field(10) + shadow_dy: int = betterproto.uint32_field(11) + shadow_radius: int = betterproto.uint32_field(12) + shadow_color: str = betterproto.string_field(13) + stroke_color: str = betterproto.string_field(14) + stroke_width: int = betterproto.uint32_field(15) + + +@dataclass +class MemberMessage(betterproto.Message): + """ԱϢ""" + + common: "Common" = betterproto.message_field(1) + user: "User" = betterproto.message_field(2) + member_count: int = betterproto.uint64_field(3) + operator: "User" = betterproto.message_field(4) + is_set_to_admin: bool = betterproto.bool_field(5) + is_top_user: bool = betterproto.bool_field(6) + rank_score: int = betterproto.uint64_field(7) + top_user_no: int = betterproto.uint64_field(8) + enter_type: int = betterproto.uint64_field(9) + action: int = betterproto.uint64_field(10) + action_description: str = betterproto.string_field(11) + user_id: int = betterproto.uint64_field(12) + effect_config: "EffectConfig" = betterproto.message_field(13) + pop_str: str = betterproto.string_field(14) + enter_effect_config: "EffectConfig" = betterproto.message_field(15) + background_image: "Image" = betterproto.message_field(16) + background_image_v2: "Image" = betterproto.message_field(17) + anchor_display_text: "Text" = betterproto.message_field(18) + public_area_common: "PublicAreaCommon" = betterproto.message_field(19) + user_enter_tip_type: int = betterproto.uint64_field(20) + anchor_enter_tip_type: int = betterproto.uint64_field(21) + + +@dataclass +class PublicAreaCommon(betterproto.Message): + user_label: "Image" = betterproto.message_field(1) + user_consume_in_room: int = betterproto.uint64_field(2) + user_send_gift_cnt_in_room: int = betterproto.uint64_field(3) + + +@dataclass +class EffectConfig(betterproto.Message): + type: int = betterproto.uint64_field(1) + icon: "Image" = betterproto.message_field(2) + avatar_pos: int = betterproto.uint64_field(3) + text: "Text" = betterproto.message_field(4) + text_icon: "Image" = betterproto.message_field(5) + stay_time: int = betterproto.uint32_field(6) + anim_asset_id: int = betterproto.uint64_field(7) + badge: "Image" = betterproto.message_field(8) + flex_setting_array_list: List[int] = betterproto.uint64_field(9) + text_icon_overlay: "Image" = betterproto.message_field(10) + animated_badge: "Image" = betterproto.message_field(11) + has_sweep_light: bool = betterproto.bool_field(12) + text_flex_setting_array_list: List[int] = betterproto.uint64_field(13) + center_anim_asset_id: int = betterproto.uint64_field(14) + dynamic_image: "Image" = betterproto.message_field(15) + extra_map: Dict[str, str] = betterproto.map_field( + 16, betterproto.TYPE_STRING, betterproto.TYPE_STRING + ) + mp4_anim_asset_id: int = betterproto.uint64_field(17) + priority: int = betterproto.uint64_field(18) + max_wait_time: int = betterproto.uint64_field(19) + dress_id: str = betterproto.string_field(20) + alignment: int = betterproto.uint64_field(21) + alignment_offset: int = betterproto.uint64_field(22) + + +@dataclass +class Text(betterproto.Message): + key: str = betterproto.string_field(1) + default_patter: str = betterproto.string_field(2) + default_format: "TextFormat" = betterproto.message_field(3) + pieces_list: List["TextPiece"] = betterproto.message_field(4) + + +@dataclass +class TextPiece(betterproto.Message): + type: bool = betterproto.bool_field(1) + format: "TextFormat" = betterproto.message_field(2) + string_value: str = betterproto.string_field(3) + user_value: "TextPieceUser" = betterproto.message_field(4) + gift_value: "TextPieceGift" = betterproto.message_field(5) + heart_value: "TextPieceHeart" = betterproto.message_field(6) + pattern_ref_value: "TextPiecePatternRef" = betterproto.message_field(7) + image_value: "TextPieceImage" = betterproto.message_field(8) + + +@dataclass +class TextPieceImage(betterproto.Message): + image: "Image" = betterproto.message_field(1) + scaling_rate: float = betterproto.float_field(2) + + +@dataclass +class TextPiecePatternRef(betterproto.Message): + key: str = betterproto.string_field(1) + default_pattern: str = betterproto.string_field(2) + + +@dataclass +class TextPieceHeart(betterproto.Message): + color: str = betterproto.string_field(1) + + +@dataclass +class TextPieceGift(betterproto.Message): + gift_id: int = betterproto.uint64_field(1) + name_ref: "PatternRef" = betterproto.message_field(2) + + +@dataclass +class PatternRef(betterproto.Message): + key: str = betterproto.string_field(1) + default_pattern: str = betterproto.string_field(2) + + +@dataclass +class TextPieceUser(betterproto.Message): + user: "User" = betterproto.message_field(1) + with_colon: bool = betterproto.bool_field(2) + + +@dataclass +class TextFormat(betterproto.Message): + color: str = betterproto.string_field(1) + bold: bool = betterproto.bool_field(2) + italic: bool = betterproto.bool_field(3) + weight: int = betterproto.uint32_field(4) + italic_angle: int = betterproto.uint32_field(5) + font_size: int = betterproto.uint32_field(6) + use_heigh_light_color: bool = betterproto.bool_field(7) + use_remote_clor: bool = betterproto.bool_field(8) + + +@dataclass +class LikeMessage(betterproto.Message): + """""" + + common: "Common" = betterproto.message_field(1) + count: int = betterproto.uint64_field(2) + total: int = betterproto.uint64_field(3) + color: int = betterproto.uint64_field(4) + user: "User" = betterproto.message_field(5) + icon: str = betterproto.string_field(6) + double_like_detail: "DoubleLikeDetail" = betterproto.message_field(7) + display_control_info: "DisplayControlInfo" = betterproto.message_field(8) + linkmic_guest_uid: int = betterproto.uint64_field(9) + scene: str = betterproto.string_field(10) + pico_display_info: "PicoDisplayInfo" = betterproto.message_field(11) + + +@dataclass +class SocialMessage(betterproto.Message): + common: "Common" = betterproto.message_field(1) + user: "User" = betterproto.message_field(2) + share_type: int = betterproto.uint64_field(3) + action: int = betterproto.uint64_field(4) + share_target: str = betterproto.string_field(5) + follow_count: int = betterproto.uint64_field(6) + public_area_common: "PublicAreaCommon" = betterproto.message_field(7) + + +@dataclass +class PicoDisplayInfo(betterproto.Message): + combo_sum_count: int = betterproto.uint64_field(1) + emoji: str = betterproto.string_field(2) + emoji_icon: "Image" = betterproto.message_field(3) + emoji_text: str = betterproto.string_field(4) + + +@dataclass +class DoubleLikeDetail(betterproto.Message): + double_flag: bool = betterproto.bool_field(1) + seq_id: int = betterproto.uint32_field(2) + renewals_num: int = betterproto.uint32_field(3) + triggers_num: int = betterproto.uint32_field(4) + + +@dataclass +class DisplayControlInfo(betterproto.Message): + show_text: bool = betterproto.bool_field(1) + show_icons: bool = betterproto.bool_field(2) + + +@dataclass +class EpisodeChatMessage(betterproto.Message): + common: "Message" = betterproto.message_field(1) + user: "User" = betterproto.message_field(2) + content: str = betterproto.string_field(3) + visible_to_sende: bool = betterproto.bool_field(4) + # BackgroundImage backgroundImage = 5; PublicAreaCommon publicAreaCommon = + # 6; + gift_image: "Image" = betterproto.message_field(7) + agree_msg_id: int = betterproto.uint64_field(8) + color_value_list: List[str] = betterproto.string_field(9) + + +@dataclass +class MatchAgainstScoreMessage(betterproto.Message): + common: "Common" = betterproto.message_field(1) + against: "Against" = betterproto.message_field(2) + match_status: int = betterproto.uint32_field(3) + display_status: int = betterproto.uint32_field(4) + + +@dataclass +class Against(betterproto.Message): + left_name: str = betterproto.string_field(1) + left_logo: "Image" = betterproto.message_field(2) + left_goal: str = betterproto.string_field(3) + # LeftPlayersList leftPlayersList = 4; LeftGoalStageDetail + # leftGoalStageDetail = 5; + right_name: str = betterproto.string_field(6) + right_logo: "Image" = betterproto.message_field(7) + right_goal: str = betterproto.string_field(8) + # RightPlayersList rightPlayersList = 9; RightGoalStageDetail + # rightGoalStageDetail = 10; + timestamp: int = betterproto.uint64_field(11) + version: int = betterproto.uint64_field(12) + left_team_id: int = betterproto.uint64_field(13) + right_team_id: int = betterproto.uint64_field(14) + diff_sei2abs_second: int = betterproto.uint64_field(15) + final_goal_stage: int = betterproto.uint32_field(16) + current_goal_stage: int = betterproto.uint32_field(17) + left_score_addition: int = betterproto.uint32_field(18) + right_score_addition: int = betterproto.uint32_field(19) + left_goal_int: int = betterproto.uint64_field(20) + right_goal_int: int = betterproto.uint64_field(21) + + +@dataclass +class Common(betterproto.Message): + method: str = betterproto.string_field(1) + msg_id: int = betterproto.uint64_field(2) + room_id: int = betterproto.uint64_field(3) + create_time: int = betterproto.uint64_field(4) + monitor: int = betterproto.uint32_field(5) + is_show_msg: bool = betterproto.bool_field(6) + describe: str = betterproto.string_field(7) + # DisplayText displayText = 8; + fold_type: int = betterproto.uint64_field(9) + anchor_fold_type: int = betterproto.uint64_field(10) + priority_score: int = betterproto.uint64_field(11) + log_id: str = betterproto.string_field(12) + msg_process_filter_k: str = betterproto.string_field(13) + msg_process_filter_v: str = betterproto.string_field(14) + user: "User" = betterproto.message_field(15) + # Room room = 16; + anchor_fold_type_v2: int = betterproto.uint64_field(17) + process_at_sei_time_ms: int = betterproto.uint64_field(18) + random_dispatch_ms: int = betterproto.uint64_field(19) + is_dispatch: bool = betterproto.bool_field(20) + channel_id: int = betterproto.uint64_field(21) + diff_sei2abs_second: int = betterproto.uint64_field(22) + anchor_fold_duration: int = betterproto.uint64_field(23) + + +@dataclass +class User(betterproto.Message): + id: int = betterproto.uint64_field(1) + short_id: int = betterproto.uint64_field(2) + nick_name: str = betterproto.string_field(3) + gender: int = betterproto.uint32_field(4) + signature: str = betterproto.string_field(5) + level: int = betterproto.uint32_field(6) + birthday: int = betterproto.uint64_field(7) + telephone: str = betterproto.string_field(8) + avatar_thumb: "Image" = betterproto.message_field(9) + avatar_medium: "Image" = betterproto.message_field(10) + avatar_large: "Image" = betterproto.message_field(11) + verified: bool = betterproto.bool_field(12) + experience: int = betterproto.uint32_field(13) + city: str = betterproto.string_field(14) + status: int = betterproto.int32_field(15) + create_time: int = betterproto.uint64_field(16) + modify_time: int = betterproto.uint64_field(17) + secret: int = betterproto.uint32_field(18) + share_qrcode_uri: str = betterproto.string_field(19) + income_share_percent: int = betterproto.uint32_field(20) + badge_image_list: List["Image"] = betterproto.message_field(21) + follow_info: "FollowInfo" = betterproto.message_field(22) + pay_grade: "PayGrade" = betterproto.message_field(23) + fans_club: "FansClub" = betterproto.message_field(24) + # Border Border = 25; + special_id: str = betterproto.string_field(26) + avatar_border: "Image" = betterproto.message_field(27) + medal: "Image" = betterproto.message_field(28) + real_time_icons_list: List["Image"] = betterproto.message_field(29) + display_id: str = betterproto.string_field(38) + sec_uid: str = betterproto.string_field(46) + fan_ticket_count: int = betterproto.uint64_field(1022) + id_str: str = betterproto.string_field(1028) + age_range: int = betterproto.uint32_field(1045) + + +@dataclass +class PayGrade(betterproto.Message): + total_diamond_count: int = betterproto.int64_field(1) + diamond_icon: "Image" = betterproto.message_field(2) + name: str = betterproto.string_field(3) + icon: "Image" = betterproto.message_field(4) + next_name: str = betterproto.string_field(5) + level: int = betterproto.int64_field(6) + next_icon: "Image" = betterproto.message_field(7) + next_diamond: int = betterproto.int64_field(8) + now_diamond: int = betterproto.int64_field(9) + this_grade_min_diamond: int = betterproto.int64_field(10) + this_grade_max_diamond: int = betterproto.int64_field(11) + pay_diamond_bak: int = betterproto.int64_field(12) + grade_describe: str = betterproto.string_field(13) + grade_icon_list: List["GradeIcon"] = betterproto.message_field(14) + screen_chat_type: int = betterproto.int64_field(15) + im_icon: "Image" = betterproto.message_field(16) + im_icon_with_level: "Image" = betterproto.message_field(17) + live_icon: "Image" = betterproto.message_field(18) + new_im_icon_with_level: "Image" = betterproto.message_field(19) + new_live_icon: "Image" = betterproto.message_field(20) + upgrade_need_consume: int = betterproto.int64_field(21) + next_privileges: str = betterproto.string_field(22) + background: "Image" = betterproto.message_field(23) + background_back: "Image" = betterproto.message_field(24) + score: int = betterproto.int64_field(25) + buff_info: "GradeBuffInfo" = betterproto.message_field(26) + grade_banner: str = betterproto.string_field(1001) + profile_dialog_bg: "Image" = betterproto.message_field(1002) + profile_dialog_bg_back: "Image" = betterproto.message_field(1003) + + +@dataclass +class FansClub(betterproto.Message): + data: "FansClubData" = betterproto.message_field(1) + prefer_data: Dict[int, "FansClubData"] = betterproto.map_field( + 2, betterproto.TYPE_INT32, betterproto.TYPE_MESSAGE + ) + + +@dataclass +class FansClubData(betterproto.Message): + club_name: str = betterproto.string_field(1) + level: int = betterproto.int32_field(2) + user_fans_club_status: int = betterproto.int32_field(3) + badge: "UserBadge" = betterproto.message_field(4) + available_gift_ids: List[int] = betterproto.int64_field(5) + anchor_id: int = betterproto.int64_field(6) + + +@dataclass +class UserBadge(betterproto.Message): + icons: Dict[int, "Image"] = betterproto.map_field( + 1, betterproto.TYPE_INT32, betterproto.TYPE_MESSAGE + ) + title: str = betterproto.string_field(2) + + +@dataclass +class GradeBuffInfo(betterproto.Message): + pass + + +@dataclass +class Border(betterproto.Message): + pass + + +@dataclass +class GradeIcon(betterproto.Message): + icon: "Image" = betterproto.message_field(1) + icon_diamond: int = betterproto.int64_field(2) + level: int = betterproto.int64_field(3) + level_str: str = betterproto.string_field(4) + + +@dataclass +class FollowInfo(betterproto.Message): + following_count: int = betterproto.uint64_field(1) + follower_count: int = betterproto.uint64_field(2) + follow_status: int = betterproto.uint64_field(3) + push_status: int = betterproto.uint64_field(4) + remark_name: str = betterproto.string_field(5) + follower_count_str: str = betterproto.string_field(6) + following_count_str: str = betterproto.string_field(7) + + +@dataclass +class Image(betterproto.Message): + url_list_list: List[str] = betterproto.string_field(1) + uri: str = betterproto.string_field(2) + height: int = betterproto.uint64_field(3) + width: int = betterproto.uint64_field(4) + avg_color: str = betterproto.string_field(5) + image_type: int = betterproto.uint32_field(6) + open_web_url: str = betterproto.string_field(7) + content: "ImageContent" = betterproto.message_field(8) + is_animated: bool = betterproto.bool_field(9) + flex_setting_list: "NinePatchSetting" = betterproto.message_field(10) + text_setting_list: "NinePatchSetting" = betterproto.message_field(11) + + +@dataclass +class NinePatchSetting(betterproto.Message): + setting_list_list: List[str] = betterproto.string_field(1) + + +@dataclass +class ImageContent(betterproto.Message): + name: str = betterproto.string_field(1) + font_color: str = betterproto.string_field(2) + level: int = betterproto.uint64_field(3) + alternative_text: str = betterproto.string_field(4) + + +@dataclass +class PushFrame(betterproto.Message): + seq_id: int = betterproto.uint64_field(1) + log_id: int = betterproto.uint64_field(2) + service: int = betterproto.uint64_field(3) + method: int = betterproto.uint64_field(4) + headers_list: List["HeadersList"] = betterproto.message_field(5) + payload_encoding: str = betterproto.string_field(6) + payload_type: str = betterproto.string_field(7) + payload: bytes = betterproto.bytes_field(8) + + +@dataclass +class Kk(betterproto.Message): + k: int = betterproto.uint32_field(14) + + +@dataclass +class SendMessageBody(betterproto.Message): + conversation_id: str = betterproto.string_field(1) + conversation_type: int = betterproto.uint32_field(2) + conversation_short_id: int = betterproto.uint64_field(3) + content: str = betterproto.string_field(4) + ext: List["ExtList"] = betterproto.message_field(5) + message_type: int = betterproto.uint32_field(6) + ticket: str = betterproto.string_field(7) + client_message_id: str = betterproto.string_field(8) + + +@dataclass +class ExtList(betterproto.Message): + key: str = betterproto.string_field(1) + value: str = betterproto.string_field(2) + + +@dataclass +class Rsp(betterproto.Message): + a: int = betterproto.int32_field(1) + b: int = betterproto.int32_field(2) + c: int = betterproto.int32_field(3) + d: str = betterproto.string_field(4) + e: int = betterproto.int32_field(5) + f: "RspF" = betterproto.message_field(6) + g: str = betterproto.string_field(7) + h: int = betterproto.uint64_field(10) + i: int = betterproto.uint64_field(11) + j: int = betterproto.uint64_field(13) + + +@dataclass +class RspF(betterproto.Message): + q1: int = betterproto.uint64_field(1) + q3: int = betterproto.uint64_field(3) + q4: str = betterproto.string_field(4) + q5: int = betterproto.uint64_field(5) + + +@dataclass +class PreMessage(betterproto.Message): + cmd: int = betterproto.uint32_field(1) + sequence_id: int = betterproto.uint32_field(2) + sdk_version: str = betterproto.string_field(3) + token: str = betterproto.string_field(4) + refer: int = betterproto.uint32_field(5) + inbox_type: int = betterproto.uint32_field(6) + build_number: str = betterproto.string_field(7) + send_message_body: "SendMessageBody" = betterproto.message_field(8) + # ֶ + aa: str = betterproto.string_field(9) + device_platform: str = betterproto.string_field(11) + headers: List["HeadersList"] = betterproto.message_field(15) + auth_type: int = betterproto.uint32_field(18) + biz: str = betterproto.string_field(21) + access: str = betterproto.string_field(22) + + +@dataclass +class HeadersList(betterproto.Message): + key: str = betterproto.string_field(1) + value: str = betterproto.string_field(2) + + +@dataclass +class LiveShoppingMessage(betterproto.Message): + common: "Common" = betterproto.message_field(1) + msg_type: int = betterproto.int32_field(2) + promotion_id: int = betterproto.int64_field(4) + + +@dataclass +class RoomStatsMessage(betterproto.Message): + common: "Common" = betterproto.message_field(1) + display_short: str = betterproto.string_field(2) + display_middle: str = betterproto.string_field(3) + display_long: str = betterproto.string_field(4) + display_value: int = betterproto.int64_field(5) + display_version: int = betterproto.int64_field(6) + incremental: bool = betterproto.bool_field(7) + is_hidden: bool = betterproto.bool_field(8) + total: int = betterproto.int64_field(9) + display_type: int = betterproto.int64_field(10) + + +@dataclass +class ProductInfo(betterproto.Message): + promotion_id: int = betterproto.int64_field(1) + index: int = betterproto.int32_field(2) + target_flash_uids_list: List[int] = betterproto.int64_field(3) + explain_type: int = betterproto.int64_field(4) + + +@dataclass +class CategoryInfo(betterproto.Message): + id: int = betterproto.int32_field(1) + name: str = betterproto.string_field(2) + promotion_ids_list: List[int] = betterproto.int64_field(3) + type: str = betterproto.string_field(4) + unique_index: str = betterproto.string_field(5) + + +@dataclass +class ProductChangeMessage(betterproto.Message): + common: "Common" = betterproto.message_field(1) + update_timestamp: int = betterproto.int64_field(2) + update_toast: str = betterproto.string_field(3) + update_product_info_list: List["ProductInfo"] = betterproto.message_field(4) + total: int = betterproto.int64_field(5) + update_category_info_list: List["CategoryInfo"] = betterproto.message_field(8) + + +@dataclass +class ControlMessage(betterproto.Message): + """ + from https://github.com/HaoDong108/DouyinBarrageGrab/blob/main/BarrageGrab/ + proto/message.proto status = 3 ² + """ + + common: "Common" = betterproto.message_field(1) + status: int = betterproto.int32_field(2) + + +@dataclass +class FansclubMessage(betterproto.Message): + """ + from https://github.com/HaoDong108/DouyinBarrageGrab/blob/main/BarrageGrab/ + proto/message.proto + """ + + common_info: "Common" = betterproto.message_field(1) + # 12 + type: int = betterproto.int32_field(2) + content: str = betterproto.string_field(3) + user: "User" = betterproto.message_field(4) + + +@dataclass +class RoomRankMessage(betterproto.Message): + """ + from https://github.com/scx567888/live-room-watcher/blob/master/src/main/pr + oto/douyin_hack/webcast/im/RoomRankMessage.proto ֱа + """ + + common: "Common" = betterproto.message_field(1) + ranks_list: List["RoomRankMessageRoomRank"] = betterproto.message_field(2) + + +@dataclass +class RoomRankMessageRoomRank(betterproto.Message): + user: "User" = betterproto.message_field(1) + score_str: str = betterproto.string_field(2) + profile_hidden: bool = betterproto.bool_field(3) + + +@dataclass +class RoomMessage(betterproto.Message): + """ + from https://github.com/scx567888/live-room- + watcher/blob/master/src/main/proto/douyin_hack/webcast/im/RoomMessage.proto + """ + + common: "Common" = betterproto.message_field(1) + content: str = betterproto.string_field(2) + supprot_landscape: bool = betterproto.bool_field(3) + roommessagetype: "RoomMsgTypeEnum" = betterproto.enum_field(4) + system_top_msg: bool = betterproto.bool_field(5) + forced_guarantee: bool = betterproto.bool_field(6) + biz_scene: str = betterproto.string_field(20) + buried_point_map: Dict[str, str] = betterproto.map_field( + 30, betterproto.TYPE_STRING, betterproto.TYPE_STRING + ) diff --git a/拉黑.py b/拉黑.py new file mode 100644 index 0000000..d859377 --- /dev/null +++ b/拉黑.py @@ -0,0 +1,1274 @@ +import os +import re +import json +import time +import pickle +import requests +from datetime import datetime +import logging +import random +import websocket +from urllib.parse import unquote +import gzip +from protobuf.douyin import * +import execjs +import hashlib +import urllib.parse +from threading import Thread +import urllib3 + +urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) + +session = requests.session() + +''' +fkgz 关注 fkfx 分享 xbwz 未知 +xbman 男 xbnv 女 quanbu 全部 wx,qq,lj,dy,tp,qt = True +wx 微信 qq qq lj 链接 +dy 抖音 tp 图片 qt 其他 +fsllsl 粉丝数量大于 gzllsl 关注数量大于 jrcssl 进入次数大于 +fsjr 粉丝进入 gzlh 关注拉黑 dammugjz 公屏关键词 +nichenggjz 昵称关键词 dqlh 地区拉黑 gxqmgjz 个性签名关键词 +IPgsd ip归属地 nlqj 年龄区间 zpsldysl 作品数量大于 +ktlv 开通蓝v smzh 私密账号 ktcc 开通橱窗 +yszh 疑似账号 IDbmd id白名单 IDhmd id黑名单 +''' + +# Settings_Options = r''' +# { +# "fkgz": false, "fkfx": false, "xbman": false, +# "xbnv": false, "xbwz": false, "quanbu": false, +# "wx": false, "qq": false, "lj": false, +# "dy": false, "tp": false, "qt": false, +# "fsjr": false, "gzlh": false, "fslldy": false, +# "gzlldy": false, "jrcsdy": false, "fsllsl": 0, +# "gzllsl": 0, "jrcssl": 0, "dammugjz": "", +# "nichenggjz": "", "ktlv": false, "ktcc": false, +# "smzh": false, "yszh": false, "zpsldy": false, +# "zpsldysl": 0, "IDbmd": "", "dqlh": "", +# "IDhmd": "", "IPgsd": "", "nlqj": "", +# "gxqmgjz": "" +# } +# ''' +Settings_Options = '''{"fkgz": false, "fkfx": false, "xbman": false, "xbnv": false, "xbwz": false, "quanbu": false, "wx": false, "qq": false, "lj": false, "dy": false, "tp": false, "qt": false, "fsjr": false, "gzlh": false, "fslldy": false, "gzlldy": false, "jrcsdy": false, "fsllsl": 0, "gzllsl": 0, "jrcssl": 0, "dammugjz": "", "nichenggjz": "", "ktlv": false, "ktcc": false, "smzh": false, "yszh": false, "zpsldy": false, "zpsldysl": 0, "IDbmd": "", "dqlh": "", "IDhmd": "", "IPgsd": "", "nlqj": "", "gxqmgjz": ""}''' +Settings_Options = json.loads(Settings_Options) + + +# 写入 拉黑_用户数据 +def write_user_data(user_name, display_id, usersid, reason): + ''' + usre_name:用户名称 + userid:用户id + usersid:用户主页id + runtime:拉黑时间 + reason:拉黑原因 + ''' + runtime = datetime.now().strftime("%Y-%m-%d %H:%M:%S") + user_data = { + "user_name": user_name, + "display_id": display_id, + 'usersid': usersid, + "runtime": runtime, + "reason": reason + } + with open('./user_data.json', 'a', encoding='utf-8') as f: + json_str = json.dump(user_data, f, ensure_ascii=False) + f.write('\n') # 每个数据对象后添加换行符 + f.close() + + +# 拉黑 +def lahei(sec_user_id, user_id, Cookie): + # 拉黑对方,需要sec_user_id和user_id + # sec_user_id:MS4wLjABAAAAhZ85ZW5BVlcjvTvpTlA6rcGIr_nhpzCSS42uSENLEqE,主页后面 + # user_id:to_uid + for __ in range(10): + try: + url = "https://www-hj.douyin.com/aweme/v1/web/user/block/?device_platform=webapp&aid=6383&channel=channel_pc_web&pc_client_type=1&pc_libra_divert=Windows&update_version_code=170400&version_code=170400&version_name=17.4.0&cookie_enabled=true&screen_width=2560&screen_height=1440&browser_language=zh-CN&browser_platform=Win32&browser_name=Chrome&browser_version=131.0.0.0&browser_online=true&engine_name=Blink&engine_version=131.0.0.0" + + # payload = "block_type=1&sec_user_id=MS4wLjABAAAAhZ85ZW5BVlcjvTvpTlA6rcGIr_nhpzCSS42uSENLEqE&source=0&user_id=61163251429" + payload = f"block_type=1&sec_user_id={sec_user_id}&source=0&user_id={user_id}" + headers = { + 'Connection': 'keep-alive', + 'Content-Length': '110', + 'Pragma': 'no-cache', + 'Cache-Control': 'no-cache', + 'sec-ch-ua-platform': '"Windows"', + 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36', + 'Accept': 'application/json, text/plain, */*', + 'sec-ch-ua': '"Google Chrome";v="131", "Chromium";v="131", "Not_A Brand";v="24"', + 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8', + 'sec-ch-ua-mobile': '?0', + 'Origin': 'https://www.douyin.com', + 'Sec-Fetch-Site': 'same-site', + 'Sec-Fetch-Mode': 'cors', + 'Sec-Fetch-Dest': 'empty', + 'Referer': 'https://www.douyin.com/', + 'Accept-Encoding': 'gzip, deflate', + 'Accept-Language': 'zh-CN,zh;q=0.9', + 'Cookie': Cookie + # 'Cookie': 'ttwid=1%7CU9RBkam_C1udCzD15RdVkhD45xIsm7PIoQlTltJYCTk%7C1732686970%7Cdc4ddd594048baeaa3df7dcdc967e36006df40e0cc901d457382909db2394dc0; UIFID_TEMP=c4a29131752d59acb78af076c3dbdd52744118e38e80b4b96439ef1e20799db082f1380d5cd13efd2ef3c0bf18206e4bfbe0e3610d3ab52bee57c5fcfdc2e02c97ca6e46bdd3de6f984ea807009371b5db9506690172d0a9a5cc4ef43373f876cd4bd5a4eac0347fff8889821f134cf0; hevc_supported=true; strategyABtestKey=%221732686972.739%22; volume_info=%7B%22isUserMute%22%3Afalse%2C%22isMute%22%3Afalse%2C%22volume%22%3A0.5%7D; FORCE_LOGIN=%7B%22videoConsumedRemainSeconds%22%3A180%7D; passport_csrf_token=52363725d47dd1229c220f0470e2f2d7; passport_csrf_token_default=52363725d47dd1229c220f0470e2f2d7; bd_ticket_guard_client_web_domain=2; d_ticket=935e0100ebe543aeb19fb88474608a1615f45; passport_assist_user=CkF9ZXWVA-iZbKerIKHDaEp1xcJZ5lh4uYUgNu1ymCM1HYElnwC0ln3nqAxRA8ByxW37RMx2pswZ8MEQWnOx-MGStBpKCjyc330xG_wrxyc791bEObH0B7n-lL2ZJD6OxxfDqLpVB69azowaOsHM72XIrf2i8PVqW5FEu4LZMQRDvogQhsriDRiJr9ZUIAEiAQMmaH5v; n_mh=07vLiXVhkr6Gw426Bs6p1qWtmm_l_Xu5Jlf1_2HXC3I; sso_uid_tt=f65780cd0e55de027bf9299f9b7dec53; sso_uid_tt_ss=f65780cd0e55de027bf9299f9b7dec53; toutiao_sso_user=331fa717c329a4f4f115118fe1f6f684; toutiao_sso_user_ss=331fa717c329a4f4f115118fe1f6f684; sid_ucp_sso_v1=1.0.0-KDY0MjVkYmNhNjBmMDUwYTRjYjQ2MDY1ZGQyNDZmZTMwMGNiZjg3NWYKIQir86C94o2KBBCZ6Zq6BhjvMSAMMM31iY8GOAZA9AdIBhoCbGYiIDMzMWZhNzE3YzMyOWE0ZjRmMTE1MTE4ZmUxZjZmNjg0; ssid_ucp_sso_v1=1.0.0-KDY0MjVkYmNhNjBmMDUwYTRjYjQ2MDY1ZGQyNDZmZTMwMGNiZjg3NWYKIQir86C94o2KBBCZ6Zq6BhjvMSAMMM31iY8GOAZA9AdIBhoCbGYiIDMzMWZhNzE3YzMyOWE0ZjRmMTE1MTE4ZmUxZjZmNjg0; login_time=1732687003098; passport_auth_status=0d63f05f5920f5fa86371e2c328c60e7%2C; passport_auth_status_ss=0d63f05f5920f5fa86371e2c328c60e7%2C; uid_tt=fe90a08ede420f1008382babb4a01af2; uid_tt_ss=fe90a08ede420f1008382babb4a01af2; sid_tt=27847273045ab5d1055ce9cc29a4cf90; sessionid=27847273045ab5d1055ce9cc29a4cf90; sessionid_ss=27847273045ab5d1055ce9cc29a4cf90; is_staff_user=false; publish_badge_show_info=%220%2C0%2C0%2C1732687004013%22; SelfTabRedDotControl=%5B%5D; _bd_ticket_crypt_doamin=2; _bd_ticket_crypt_cookie=388b6415a7b774ecbb771fd4e6bb8f78; __security_server_data_status=1; sid_guard=27847273045ab5d1055ce9cc29a4cf90%7C1732687005%7C5183999%7CSun%2C+26-Jan-2025+05%3A56%3A44+GMT; sid_ucp_v1=1.0.0-KDk2M2NmYmU2NjkxZTQxYTUwOGM4NzgxMmNhZmQ0YjUxZWYwODBlZmMKGwir86C94o2KBBCd6Zq6BhjvMSAMOAZA9AdIBBoCaGwiIDI3ODQ3MjczMDQ1YWI1ZDEwNTVjZTljYzI5YTRjZjkw; ssid_ucp_v1=1.0.0-KDk2M2NmYmU2NjkxZTQxYTUwOGM4NzgxMmNhZmQ0YjUxZWYwODBlZmMKGwir86C94o2KBBCd6Zq6BhjvMSAMOAZA9AdIBBoCaGwiIDI3ODQ3MjczMDQ1YWI1ZDEwNTVjZTljYzI5YTRjZjkw; store-region=cn-fj; store-region-src=uid; biz_trace_id=41025dff; is_dash_user=1; SEARCH_RESULT_LIST_TYPE=%22single%22; pwa2=%220%7C0%7C3%7C0%22; my_rd=2; live_use_vvc=%22false%22; h265ErrorNum=-1; webcast_local_quality=origin; stream_player_status_params=%22%7B%5C%22is_auto_play%5C%22%3A0%2C%5C%22is_full_screen%5C%22%3A0%2C%5C%22is_full_webscreen%5C%22%3A0%2C%5C%22is_mute%5C%22%3A0%2C%5C%22is_speed%5C%22%3A1%2C%5C%22is_visible%5C%22%3A0%7D%22; __live_version__=%221.1.2.5721%22; live_can_add_dy_2_desktop=%221%22; stream_recommend_feed_params=%22%7B%5C%22cookie_enabled%5C%22%3Atrue%2C%5C%22screen_width%5C%22%3A2560%2C%5C%22screen_height%5C%22%3A1440%2C%5C%22browser_online%5C%22%3Atrue%2C%5C%22cpu_core_num%5C%22%3A28%2C%5C%22device_memory%5C%22%3A8%2C%5C%22downlink%5C%22%3A10%2C%5C%22effective_type%5C%22%3A%5C%224g%5C%22%2C%5C%22round_trip_time%5C%22%3A0%7D%22; FOLLOW_LIVE_POINT_INFO=%22MS4wLjABAAAAcfYfvFRPvoxRdGJHhNk26Vx0J0Nf9RmuUggT6CeeVxivnBYc1nRoJTwq_N2a6dJs%2F1732723200000%2F0%2F0%2F1732697858379%22; FOLLOW_NUMBER_YELLOW_POINT_INFO=%22MS4wLjABAAAAcfYfvFRPvoxRdGJHhNk26Vx0J0Nf9RmuUggT6CeeVxivnBYc1nRoJTwq_N2a6dJs%2F1732723200000%2F0%2F1732697258380%2F0%22; bd_ticket_guard_client_data=eyJiZC10aWNrZXQtZ3VhcmQtdmVyc2lvbiI6MiwiYmQtdGlja2V0LWd1YXJkLWl0ZXJhdGlvbi12ZXJzaW9uIjoxLCJiZC10aWNrZXQtZ3VhcmQtcmVlLXB1YmxpYy1rZXkiOiJCTmRrNUtCTjlJMWk4TW15V1RVMzdxcC9aSEI4WWU2My81M0VDdFF6Nk9pWk4wRVl0K2V4M1UydFZ1bmZ4dFM0V0NxYnVTd1U0NE9HeTdHdFpPajR4STA9IiwiYmQtdGlja2V0LWd1YXJkLXdlYi12ZXJzaW9uIjoyfQ%3D%3D; home_can_add_dy_2_desktop=%221%22; WallpaperGuide=%7B%22showTime%22%3A0%2C%22closeTime%22%3A0%2C%22showCount%22%3A0%2C%22cursor1%22%3A29%2C%22cursor2%22%3A8%7D; odin_tt=1b03c18d171dadef1f2d74f0110f49f52593545553a4eef411d09c01a0fdc369f1aa8355e2dd9f85ce81034ff8c843c8; IsDouyinActive=true' + } + + response = requests.request("POST", url, headers=headers, data=payload, timeout=3, verify=False) + # '{"status_code":0,"block_status":1,"extra":{"now":1732697940000,"fatal_item_ids":[],"logid":"20241127165900C4E8A38FAAFFE50C3E07"},"log_pb":{"impr_id":"20241127165900C4E8A38FAAFFE50C3E07"}}' + if '"status_code":0' in response.text: + return True + else: + # print(response.text) + return False + except Exception as e: + print('lahei', e) + + return False + + +# 解除拉黑 +def jclahei(sec_user_id, Cookie, user_id='7454438944119719433'): + ''' + + :param sec_user_id: + :param user_id:抖音的user_unique_id值, + :param Cookie: + :return: + ''' + for __ in range(10): + try: + url = "https://www.douyin.com/aweme/v1/web/user/block/?device_platform=webapp&aid=6383&channel=channel_pc_web&pc_client_type=1&pc_libra_divert=Windows&update_version_code=170400&version_code=170400&version_name=17.4.0&cookie_enabled=true&screen_width=2560&screen_height=1440&browser_language=zh-CN&browser_platform=Win32&browser_name=Chrome&browser_version=131.0.0.0&browser_online=true&engine_name=Blink&engine_version=131.0.0.0&os_name=Windows&os_version=10&cpu_core_num=28&device_memory=8&platform=PC&downlink=10&effective_type=4g&round_trip_time=0" + + payload = f"block_type=0&sec_user_id={sec_user_id}&source=0&user_id={user_id}" + headers = { + 'Connection': 'keep-alive', + 'Pragma': 'no-cache', + 'Cache-Control': 'no-cache', + 'sec-ch-ua-platform': '"Windows"', + 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36', + 'Accept': 'application/json, text/plain, */*', + 'x-secsdk-csrf-token': 'fHFd=f24ms8IC7K0tv7Zr5yGw69vgstUyiXltzg3pxxtfaQOTRCbXlMU08taG5frPAnrKFo3FN6gXANTYVyn47qi=KY6IgaSiTYosAF939T', + 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8', + 'Referer': f'https://www.douyin.com/user/{sec_user_id}', + 'Accept-Encoding': 'gzip, deflate', + 'Accept-Language': 'zh-CN,zh;q=0.9', + # 'Cookie': 'ttwid=1%7CKWXadMDhW9Ryw_ADwbeFK_FV9H-mbn3vFxyte2YAZL8%7C1735621839%7C2023a3817009a569d35894b430f6575ba57c352aa1c8d409409e8419fe2eeac2; UIFID_TEMP=c4a29131752d59acb78af076c3dbdd52744118e38e80b4b96439ef1e20799db02e8e7a5a86363a89fcec77e2d646615eca416b0564627981e02f280480cc7a0b5215a3f91585358e92dd2f7c4807c5002acaaeb100519902234feddc5b68b02bdfe0e29a074b2bf5645cc1afe4195533; s_v_web_id=verify_m5c0fj24_two4VH2Q_uopw_4bO1_9hhn_C0Tcq87kZcJx; hevc_supported=true; dy_swidth=2560; dy_sheight=1440; my_rd=2; fpk1=U2FsdGVkX19XIyl6qGLvr1yaDzNIntOXA6m8G57S4sifGptdOC7CTzX9RIcI5U2LTTFFHXrkPzUGHbjQ7CfRqw==; fpk2=f51bb482c660d0eeadd1f058058a2b35; bd_ticket_guard_client_web_domain=2; passport_csrf_token=8521596f974a978da1e4b354eb1d35c1; passport_csrf_token_default=8521596f974a978da1e4b354eb1d35c1; UIFID=c4a29131752d59acb78af076c3dbdd52744118e38e80b4b96439ef1e20799db02e8e7a5a86363a89fcec77e2d646615eca416b0564627981e02f280480cc7a0bed8fe6dddf462035cabdbffe88852cd4b880a1ac63ce66c05dd898d871d0d9a56122b3387b3aa1bca9b18d5e63727b923ccb09fb874d403178c3c7e258b20a2d2fd65f7e5e111c28ea1fa9ccfbeca9d86001470e9b5c68ef98f37b8469b938d87d0877f83a459825f9347573727217b7b20b2bedc1b0bbef9547713cd654f778; FORCE_LOGIN=%7B%22videoConsumedRemainSeconds%22%3A180%2C%22isForcePopClose%22%3A1%7D; is_dash_user=1; __ac_nonce=06775f84a00347ad53f19; __ac_signature=_02B4Z6wo00f01zRL7KAAAIDDA28o.PttSTc0a-gAAKpx60; csrf_session_id=6432c96e165f150b78c22e8447711030; passport_assist_user=Cjzgvg6j8zBZnJqRpkCuCFVCSD6GgohNh0pytKoNp5NXG8lLVmaH3x7_XmHVcBTSbN2B6zNCOQI6-gL6geAaSgo85CasOHZYo_u95TNfT5dF1YykMfnegAC-GyhVlQFvWalAh_Fm3XQuAdpHKHIKdDy5ZQZ441_9kQQZZWeXEPrc5Q0Yia_WVCABIgED7P5X0Q%3D%3D; n_mh=9-mIeuD4wZnlYrrOvfzG3MuT6aQmCUtmr8FxV8Kl8xY; sso_uid_tt=183c57659c43eeceaed318796ff7f102; sso_uid_tt_ss=183c57659c43eeceaed318796ff7f102; toutiao_sso_user=ca675dcc5f006efc313dc69f7e3e0ccb; toutiao_sso_user_ss=ca675dcc5f006efc313dc69f7e3e0ccb; sid_ucp_sso_v1=1.0.0-KGY3MDY2NWZlZjFlNTk2NDRjOTc4ZTc2YzdhOGIxNmY4YjFlYjEzMDYKHQicjOfinAIQ3vDXuwYY7zEgDDC7psTQBTgGQPQHGgJscSIgY2E2NzVkY2M1ZjAwNmVmYzMxM2RjNjlmN2UzZTBjY2I; ssid_ucp_sso_v1=1.0.0-KGY3MDY2NWZlZjFlNTk2NDRjOTc4ZTc2YzdhOGIxNmY4YjFlYjEzMDYKHQicjOfinAIQ3vDXuwYY7zEgDDC7psTQBTgGQPQHGgJscSIgY2E2NzVkY2M1ZjAwNmVmYzMxM2RjNjlmN2UzZTBjY2I; login_time=1735784542133; passport_auth_status=577638629195a1c78981dcc18eb6914d%2C; passport_auth_status_ss=577638629195a1c78981dcc18eb6914d%2C; uid_tt=be33504736d799b7e42458a52241a944; uid_tt_ss=be33504736d799b7e42458a52241a944; sid_tt=3a7970ea751f676dce010b635f8d19b1; sessionid=3a7970ea751f676dce010b635f8d19b1; sessionid_ss=3a7970ea751f676dce010b635f8d19b1; is_staff_user=false; _bd_ticket_crypt_doamin=2; _bd_ticket_crypt_cookie=c2194fa0fb2ed4598e93bbead8b2ec09; __security_server_data_status=1; publish_badge_show_info=%220%2C0%2C0%2C1735784550346%22; passport_fe_beating_status=true; sid_guard=3a7970ea751f676dce010b635f8d19b1%7C1735784552%7C5183993%7CMon%2C+03-Mar-2025+02%3A22%3A25+GMT; sid_ucp_v1=1.0.0-KGUyNWE1YzdkYjc1Zjg3ODMzZDQ4NTFjYjU4ODhlN2Y1MjI2ODkxZWEKGQicjOfinAIQ6PDXuwYY7zEgDDgGQPQHSAQaAmxxIiAzYTc5NzBlYTc1MWY2NzZkY2UwMTBiNjM1ZjhkMTliMQ; ssid_ucp_v1=1.0.0-KGUyNWE1YzdkYjc1Zjg3ODMzZDQ4NTFjYjU4ODhlN2Y1MjI2ODkxZWEKGQicjOfinAIQ6PDXuwYY7zEgDDgGQPQHSAQaAmxxIiAzYTc5NzBlYTc1MWY2NzZkY2UwMTBiNjM1ZjhkMTliMQ; FOLLOW_NUMBER_YELLOW_POINT_INFO=%22MS4wLjABAAAAHZbJJ5e8g4Lk0PIezttIs-bJdhhLb79nOZeFZVjop6o%2F1735833600000%2F1735784585664%2F1735784545513%2F0%22; SelfTabRedDotControl=%5B%5D; volume_info=%7B%22isUserMute%22%3Afalse%2C%22isMute%22%3Afalse%2C%22volume%22%3A0.5%7D; strategyABtestKey=%221735784593.663%22; biz_trace_id=18f02cfb; store-region=cn-fj; store-region-src=uid; stream_recommend_feed_params=%22%7B%5C%22cookie_enabled%5C%22%3Atrue%2C%5C%22screen_width%5C%22%3A2560%2C%5C%22screen_height%5C%22%3A1440%2C%5C%22browser_online%5C%22%3Atrue%2C%5C%22cpu_core_num%5C%22%3A28%2C%5C%22device_memory%5C%22%3A8%2C%5C%22downlink%5C%22%3A10%2C%5C%22effective_type%5C%22%3A%5C%224g%5C%22%2C%5C%22round_trip_time%5C%22%3A0%7D%22; download_guide=%223%2F20250102%2F0%22; IsDouyinActive=true; home_can_add_dy_2_desktop=%221%22; bd_ticket_guard_client_data=eyJiZC10aWNrZXQtZ3VhcmQtdmVyc2lvbiI6MiwiYmQtdGlja2V0LWd1YXJkLWl0ZXJhdGlvbi12ZXJzaW9uIjoxLCJiZC10aWNrZXQtZ3VhcmQtcmVlLXB1YmxpYy1rZXkiOiJCSnhRZURwVm5RV2RCWHYyUDdsQkZBQ2grK3hnZW5DZElkS3pML0lqUy9aTXByVWo2ajJUQ1lxUzlxM2pqcThUbWVHR2lET3dpQkMwWnRkbDdKblB2Vnc9IiwiYmQtdGlja2V0LWd1YXJkLXdlYi12ZXJzaW9uIjoyfQ%3D%3D; odin_tt=6428f310d4802afd53a00105de9cc307b50976cb366ec2c003f57d3ad6a461b8a0bee9972f745cb565544ae3f7faab23c3376ad4c22dedbd04e5517c14b449bb' + } + + response = requests.request("POST", url, headers=headers, data=payload, timeout=3, verify=False, + cookies=Cookie) + + if response.status_code == 200: + if '"status_code":0' in response.text: + return True + else: + # print(response.text) + return response.text + else: + return response.status_code + + except Exception as e: + print('jclahei', e) + + return False + + +# 读取cookie +def load_cookies_from_file(filename): + # 以二进制写入模式打开文件 + + with open(filename, "rb") as f: + return pickle.load(f) + + +# 取随机ua +def zhengchang_ua(i): + # return 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/106.0.0.0 Safari/537.36 Edg/106.0.1370.42' + if i == 0: + first_num = random.randint(55, 62) + third_num = random.randint(0, 3200) + fourth_num = random.randint(0, 140) + os_type = [ + "(Linux; Android 10; MI 9 Build/QKQ1.190825.002; wv)", + "(Linux; Android 8.1.0; PBCM30 Build/OPM1.171019.011; wv)", + "(Linux; Android 6.0; HUAWEI MLA-AL10 Build/HUAWEIMLA-AL10; wv)", + "(Linux; Android 6.0.1; OPPO A57t Build/MMB29M; wv)", + "(iPhone; CPU iPhone OS 10_3_3 like Mac OS X)", + "(Linux; U; Android 9; zh-cn; Redmi 7 Build/PKQ1.181021.001)", + "(Linux; Android 9; V1914A Build/PKQ1.181016.001; wv)", + "(Linux; U; Android 10; zh-CN; ALP-AL00 Build/HUAWEIALP-AL00)", + "(Linux; Android 10; VOG-TL00 Build/HUAWEIVOG-TL00; wv)", + "(Linux; Android 9; Nokia X7 Build/PPR1.180610.011; wv)", + "(Linux; Android 9.0; S5 Build/PKQ1.190319.001; wv)", + "(Linux; Android 10; PCT-AL10 Build/HUAWEIPCT-AL10; wv)", + "(Linux; Android 10; PCT-AL10 Build/HUAWEIPCT-AL10; wv)", + "(Linux; Android 9; Mi9 Pro 5G Build/PKQ1.190714.001; wv)", + "(iPhone; CPU iPhone OS 13_4 like Mac OS X)", + "(Linux; Android 10; OXF-AN00 Build/HUAWEIOXF-AN00; wv)", + "(Linux; U; Android 9; zh-cn; V1814A Build/PKQ1.180819.001)", + "(Linux; U; Android 7.0; zh-cn; Redmi Note 4X Build/NRD90M)", + "(Linux; Android 9; RMX1991 Build/PKQ1.190630.001; wv)", + "(Linux; Android 10; JNY-AL10 Build/HUAWEIJNY-AL10; wv)", + "(Linux; Android 10; ELE-AL00 Build/HUAWEIELE-AL00; wv)", + "(Linux; Android 9; RMX1991 Build/PKQ1.190630.001; wv)", + "(Linux; U; Android 10; zh-cn; MI 8 Build/QKQ1.190828.002)", + "(Linux; Android 10; VCE-AL00 Build/HUAWEIVCE-AL00; wv)", + "(Linux; Android 8.0.0; AUM-TL20 Build/HONORAUM-TL20; wv)", + "(Linux; Android 10; ALP-AL00 Build/HUAWEIALP-AL00; wv)", + "(Linux; U; Android 10; zh-cn; MI 8 SE Build/QKQ1.190828.002)", + "(Linux; Android 7.1.1; OPPO A83 Build/N6F26Q; wv)", + "(Linux; Android 10; VOG-AL10 Build/HUAWEIVOG-AL10; wv)", + "(iPhone; CPU iPhone OS 13_3_1 like Mac OS X)", + "(Linux; U; Android 10; zh-cn; MI 9 Build/QKQ1.190825.002)", + "(Linux; Android 9; INE-TL00 Build/HUAWEIINE-TL00; wv)", + "(Linux; Android 9; ONEPLUS A6000 Build/PKQ1.180716.001; wv)", + "(Linux; U; Android 9; zh-cn; Mi9 Pro 5G Build/PKQ1.190714.001)", + "(Linux; Android 8.1.0; OPPO R11 Plus Build/OPM1.171019.011; wv)", + "(Linux; Android 8.1.0; COR-AL00 Build/HUAWEICOR-AL00; wv)", + "(Linux; Android 7.1.2; M15 Build/N2G47H; wv)", + "(Linux; arm_64; Android 7.0; LG-H870DS)", + "(Linux; U; Android 9; zh-cn; MI CC9 Pro Build/PKQ1.190302.001)", + "(Linux; Android 10; SM-G9730 Build/QP1A.190711.020; wv)", + "(Linux; Android 7.1.2; Hisense A2T Build/N2G47H; wv)", + "(Linux; U; Android 8.1.0; zh-CN; 16th Plus Build/OPM1.171019.026)", + "(Linux; U; Android 9; zh-cn; MI 8 Lite Build/PKQ1.181007.001)", + "(Linux; Android 9; PAAM00 Build/PKQ1.190414.001; wv)", + "(iPhone; CPU iPhone OS 10_1_1 like Mac OS X)", + "(iPhone; CPU iPhone OS 11_4_1 like Mac OS X)", + "(Linux; Android 9; V1914A Build/PKQ1.181016.001; wv)", + "(Linux; Android 10; PCT-AL10 Build/HUAWEIPCT-AL10; wv)", + ] + chrome_version = "Chrome/{}.0.{}.{}".format(first_num, third_num, fourth_num) + + ua = " ".join( + [ + "Mozilla/5.0", + random.choice(os_type), + "AppleWebKit/537.36", + "(KHTML, like Gecko)", + chrome_version, + "Safari/537.36", + ] + ) + return ua + elif i == 1: + os_type = [ + "(Windows NT 6.1; WOW64)", + "(Windows NT 6.0; WOW64)", + "(Windows NT 6.2; WOW64)", + "(Windows NT 6.3; WOW64)", + "(Windows NT 5.1; WOW64)", + "(Windows NT 5.0; WOW64)", + "(Windows NT 5.2; WOW64)", + "(Windows NT 5.3; WOW64)", + "(Windows NT 10.1; WOW64)", + "(Windows NT 10.0; WOW64)", + "(Windows NT 10.2; WOW64)", + "(Windows NT 10.3; WOW64)", + "(Windows NT 6.1; WOW64; X64)", + "(Windows NT 6.0; WOW64; X64)", + "(Windows NT 6.2; WOW64; X64)", + "(Windows NT 6.3; WOW64; X64)", + "(Windows NT 5.1; WOW64; X64)", + "(Windows NT 5.0; WOW64; X64)", + "(Windows NT 5.2; WOW64; X64)", + "(Windows NT 5.3; WOW64; X64)", + "(Windows NT 10.1; WOW64; X64)", + "(Windows NT 10.0; WOW64; X64)", + "(Windows NT 10.2; WOW64; X64)", + "(Windows NT 10.3; WOW64; X64)", + "(Windows NT 6.1)", + "(Windows NT 6.0)", + "(Windows NT 6.2)", + "(Windows NT 6.3)", + "(Windows NT 5.1)", + "(Windows NT 5.0)", + "(Windows NT 5.2)", + "(Windows NT 5.3)", + "(Windows NT 10.1)", + "(Windows NT 10.0)", + "(Windows NT 10.2)", + "(Windows NT 10.3)", + ] + banben = ( + str(random.randint(47, 170)) + + ".0." + + str(random.randint(2000, 2755)) + + "." + + str(random.randint(0, 25)) + ) + + ua = " ".join( + [ + "Mozilla/5.0", + random.choice(os_type), + "AppleWebKit/537.36", + "(KHTML, like Gecko)", + "Chrome/" + banben, + "Safari/537.36", + ] + ) + return ua + elif i == 2: + os_type = [ + "(Macintosh; U; PPC Mac OS X 10_5_8; ja-jp)", + "(Windows; U; Windows NT 6.1; cs-CZ)", + "(Windows; U; Windows NT 6.0; tr-TR)", + "(Windows; U; Windows NT 5.1; ru-RU)", + "(Windows; U; Windows NT 6.0; tr-TR)", + "(Macintosh; Intel Mac OS X 10_6_8)", + "(Windows; U; Windows NT 6.1; zh-HK)", + "(Windows; U; Windows NT 6.0; ja-JP)", + "(Windows; U; Windows NT 6.0; hu-HU)", + "(Macintosh; U; Intel Mac OS X 10_6_6; de-de)", + "(Windows; U; Windows NT 6.1; ko-KR)", + "(Macintosh; Intel Mac OS X 10_7_3)", + "(Macintosh; U; PPC Mac OS X 10_5_8; ja-jp)", + "(Windows; U; Windows NT 6.1; sv-SE)", + "(Macintosh; U; Intel Mac OS X 10_6_6; fr-ch)", + "(Windows; U; Windows NT 6.1; de-DE)", + "(Windows; U; Windows NT 6.0; de-DE)", + "(Macintosh; U; Intel Mac OS X 10_5_8; zh-cn)", + "(Macintosh; U; Intel Mac OS X 10_6_6; ja-jp)", + "(Windows; U; Windows NT 6.0; en-US)", + ] + banben = ( + str(random.randint(533, 534)) + + "." + + str(random.randint(18, 21)) + + "." + + str(random.randint(1, 27)) + ) + chrome_version = [ + "Version/5.0.3", + "Version/5.0.4", + "Version/5.0.2", + "Version/7.0.3", + "Version/6.0 Mobile/10A5355d", + "Version/5.1.7", + "Version/5.1.6", + "Version/5.1.3", + "Version/5.1.4", + "Version/5.1.2", + "Version/5.1.3", + ] + + ua = " ".join( + [ + "Mozilla/5.0", + random.choice(os_type), + "AppleWebKit/" + banben, + "(KHTML, like Gecko)", + random.choice(chrome_version), + "Safari/" + banben, + ] + ) + return ua + elif i == 3: + os_type = [ + "(Windows NT 10.0; Win64; x64; rv:", + "(Windows NT 6.3; Win64; x64; rv:", + "(Windows NT 6.2; Win64; x64; rv:", + "(Windows NT 10; rv:", + "(Windows NT 6.3; rv:", + "(Windows NT 6.2; rv:", + "(Windows NT 6.1; rv:", + "(Windows NT 6.1; Win64; x64; rv:", + "(X11; Linux i586; rv:", + "(Windows NT 10.0; Win64; x64; rv:", + ] + banben = str(random.randint(20, 50)) + ".0" + chrome_version = [ + "Gecko/20100101 Firefox/", + "Gecko/20130405 Firefox/", + "Gecko/20130330 Firefox/", + "Gecko/20130430 Firefox/", + "Gecko/20140230 Firefox/", + "Gecko/20140630 Firefox/", + "Gecko/20140512 Firefox/", + "Gecko/20140712 Firefox/", + "Gecko/20100502 Firefox/", + ] + + ua = " ".join( + [ + "Mozilla/5.0", + random.choice(os_type) + banben + ")", + random.choice(chrome_version) + banben, + ] + ) + return ua + elif i == 4: + os_type = [ + "(Macintosh; U; Intel Mac OS X 10_6_7; ", + "(Macintosh; U; Intel Mac OS X 10_6_5; ", + "(Windows; U; Windows NT 6.1; ", + "(Macintosh; U; Intel Mac OS X 10_6_6; ", + "(Windows; U; Windows NT 6.0; ", + "(Windows; U; Windows NT 6.1; ", + "(Windows; U; Windows NT 5.1; ", + "(Macintosh; U; Intel Mac OS X 10_6_6; ", + "(Macintosh; U; PPC Mac OS X 10_5_8;", + "(Macintosh; U; Intel Mac OS X 10_6_7;", + "(Macintosh; U; Intel Mac OS X 10_6_5;", + "(Macintosh; U; Intel Mac OS X 10_6_6;", + ] + diqu = [ + "ja-jp)", + "de-de)", + "de-DE)", + "fr-ch)", + "en-US)", + "cs-CZ)", + "it-it)", + "ko-kr)", + "da-dk)", + "ar)", + "hu-HU)", + "ko-KR)", + "es-es)", + "zh-HK)", + "en-gb)", + ] + banben = ( + str(random.randint(532, 535)) + + "." + + str(random.randint(19, 55)) + + "." + + str(random.randint(1, 25)) + ) + + ua = " ".join( + [ + "Mozilla/5.0", + random.choice(os_type) + random.choice(diqu), + "AppleWebKit/" + banben, + "(KHTML, like Gecko)", + "Version/5.0." + str(random.randint(1, 5)), + "Safari/" + banben, + ] + ) + return ua + elif i == 5: + os_type = [ + "(Windows; U; Windows NT 5.1", + "(Macintosh; U; Intel Mac OS X 10_6_6", + "(Macintosh; U; PPC Mac OS X 10_5_8", + "(Macintosh; U; Intel Mac OS X 10_6_7", + "(Macintosh; U; Intel Mac OS X 10_6_5", + "(Macintosh; U; Intel Mac OS X 10_6_6", + "(Macintosh; AMD Mac OS X 10_8_2", + "(Macintosh; Intel Mac OS X 10_10_1", + "(Macintosh; Intel Mac OS X 10_5_8", + "(Macintosh; Intel Mac OS X 10_6_0", + "(Macintosh; Intel Mac OS X 10_6_2", + "(Macintosh; Intel Mac OS X 10_6_3", + "(Macintosh; Intel Mac OS X 10_6_4", + "(Macintosh; Intel Mac OS X 10_6_5", + "(Macintosh; Intel Mac OS X 10_6_6", + "(Macintosh; Intel Mac OS X 10_6_7", + "(Macintosh; Intel Mac OS X 10_6_8", + "(Macintosh; Intel Mac OS X 10_7_0", + "(Macintosh; Intel Mac OS X 10_7_1", + "(Macintosh; Intel Mac OS X 10_7_2", + "(Macintosh; Intel Mac OS X 10_7_3", + "(Macintosh; Intel Mac OS X 10_7_4", + "(Macintosh; Intel Mac OS X 10_7_5", + "(Macintosh; Intel Mac OS X 10_8_0", + "(Macintosh; Intel Mac OS X 10_8_1", + "(Macintosh; Intel Mac OS X 10_8_2", + "(Macintosh; Intel Mac OS X 10_8_3", + "(Macintosh; Intel Mac OS X 10_9_0", + "(Macintosh; Intel Mac OS X 10_9_1", + "(Macintosh; Intel Mac OS X 10_9_2", + "(Macintosh; Intel Mac OS X 10_9_3", + "(Macintosh; PPC Mac OS X 10_6_7", + "(Macintosh; U; Intel Mac OS X 10_5_6", + "(Macintosh; U; Intel Mac OS X 10_5_7", + "(Macintosh; U; Intel Mac OS X 10_5_8", + "(Macintosh; U; Intel Mac OS X 10_5_9", + "(Macintosh; U; Intel Mac OS X 10_6_0", + "(Macintosh; U; Intel Mac OS X 10_6_1", + "(Macintosh; U; Intel Mac OS X 10_6_2", + "(Macintosh; U; Intel Mac OS X 10_6_3", + "(Macintosh; U; Intel Mac OS X 10_6_4", + "(Macintosh; U; Intel Mac OS X 10_6_5", + "(Macintosh; U; Intel Mac OS X 10_6_6", + "(Macintosh; U; Intel Mac OS X 10_6_7", + "(Macintosh; U; Intel Mac OS X 10_6_8", + "(Macintosh; U; Intel Mac OS X 10_8", + ] + diqu = [ + "; ja-jp)", + "; e-de)", + "; de-DE)", + "; fr-ch)", + "; en-US)", + "; cs-CZ)", + "; it-it)", + "; ko-kr)", + "; da-dk)", + "; ar)", + "; hu-HU)", + "; ko-KR)", + "; es-es)", + "; zh-HK)", + "; en-gb)", + "; id-ID)", + ] + banben = ( + str(random.randint(500, 535)) + + "." + + str(random.randint(0, 55)) + + "." + + str(random.randint(0, 25)) + ) + + ua = " ".join( + [ + "Mozilla/5.0", + random.choice(os_type) + random.choice(diqu), + "AppleWebKit/" + banben, + "(KHTML, like Gecko)", + "Version/5.0." + str(random.randint(1, 9)), + "Safari/" + banben, + ] + ) + return ua + else: + os_type = [ + "(iPhone; U; CPU iPhone OS 4_3_1 like Mac OS X", + "(iPhone; U; CPU iPhone OS 4_2_1 like Mac OS X", + "(iPhone; U; CPU iPhone OS 4_3 like Mac OS X", + "(iPhone; U; CPU iPhone OS 4_2_4 like Mac OS X", + "(iPhone; CPU iPhone OS 12_1_4 like Mac OS X", + "(iPhone; CPU iPhone OS 12_0 like Mac OS X", + "(iPhone; CPU iPhone OS 11_2 like Mac OS X", + "(iPhone 6s; CPU iPhone OS 11_4_1 like Mac OS X", + "(iPhone; CPU iPhone OS 10_1 like Mac OS X", + "(iPhone; CPU iPhone OS 11_0_2 like Mac OS X", + "(iPhone; CPU iPhone OS 11_4_1 like Mac OS X", + "(iPhone; CPU iPhone OS 10_1_1 like Mac OS X", + "(iPhone; CPU iPhone OS 13_5_1 like Mac OS X", + "(iPhone; CPU iPhone OS 8_3 like Mac OS X", + "(iPhone; CPU iPhone OS 14_4 like Mac OS X", + "(iPhone; CPU iPhone OS 13_6 like Mac OS X", + "(iPhone; CPU iPhone OS 14_1 like Mac OS X", + "(iPhone; CPU iPhone OS 13_6_1 like Mac OS X", + ] + diqu = [ + "; ja-jp)", + "; e-de)", + "; de-DE)", + "; fr-ch)", + "; en-US)", + "; cs-CZ)", + "; it-it)", + "; ko-kr)", + "; da-dk)", + "; ar)", + "; hu-HU)", + "; ko-KR)", + "; es-es)", + "; zh-HK)", + "; en-gb)", + "; id-ID)", + ] + banben = ( + str(random.randint(500, 535)) + + "." + + str(random.randint(0, 55)) + + "." + + str(random.randint(0, 25)) + ) + + mobi = [ + "Version/6.0 Mobile/10A5355d", + "Version/5.1 Mobile/9B176", + "Version/5.0.2 Mobile/8J2", + "Version/5.0.2 Mobile/8G4", + "Version/5.0.2 Mobile/8C148", + "Version/5.0.2 Mobile/8C148a", + "Version/5.0.2 Mobile/8G4", + "Version/5.0.2 Mobile/8F190", + "Version/4.0.5 Mobile/8B5097d", + "Version/4.0.5 Mobile/8B117", + "Version/4.0.4 Mobile/7B314", + "Version/4.0.4 Mobile/7B334b", + "Version/4.0.4 Mobile/7D11", + "Version/4.0.4 Mobile/7B500", + "Version/4.0.4 Mobile/7B360", + "Version/3.1.1 Mobile/5G77", + ] + + ua = " ".join( + [ + "Mozilla/5.0", + random.choice(os_type) + random.choice(diqu), + "AppleWebKit/" + banben, + "(KHTML, like Gecko)", + random.choice(mobi), + "Safari/" + banben, + ] + ) + return ua + + +# wss链接加密 获取 signature +def generateSignature(wss): + """ + 出现gbk编码问题则修改 python模块subprocess.py的源码中Popen类的__init__函数参数encoding值为 "utf-8" + """ + params = ( + "live_id,aid,version_code,webcast_sdk_version," + "room_id,sub_room_id,sub_channel_id,did_rule," + "user_unique_id,device_platform,device_type,ac," + "identity" + ).split(",") + wss_params = urllib.parse.urlparse(wss).query.split("&") + wss_maps = {i.split("=")[0]: i.split("=")[-1] for i in wss_params} + tpl_params = [f"{i}={wss_maps.get(i, '')}" for i in params] + param = ",".join(tpl_params) + md5 = hashlib.md5() + md5.update(param.encode()) + md5_param = md5.hexdigest() + + # with codecs.open('D:\job_demo\demo\day04\h_sign.js', 'r', encoding='utf8') as f: + # script = f.read() + + # ctx = MiniRacer() + # ctx.eval(script) + + with open("h_sign.js", "r", encoding="utf-8") as f: + js_code = f.read() + ctx = execjs.compile(js_code) + + try: + signature = ctx.call("get_sign", md5_param) + return signature + except Exception as e: + print(e) + + +# 检索关键词拉黑 +def char_in_list(string, char_list): + """ + 判断字符串中的某个字符是否在列表元素中 + + :param char: 要检查的字符 + :param char_list: 字符列表 + :return: 如果字符在列表中则返回True,否则返回False + """ + for char in char_list.split('\n'): + if char == '': + continue + if char in string: + print(char) + return True + return False + + +# 查看用户主页信息 +def View_user_home(uid, Cookies): + # 访问主页,获取用户信息,只有登录才能获取地区 + for __ in range(10): + try: + + # session = requests.Session() + # session.mount('https://www.douyin.com', DESAdapter()) + url = "https://www.douyin.com/user/" + uid + headers = { + 'Connection': 'keep-alive', + 'Pragma': 'no-cache', + 'Cache-Control': 'no-cache', + 'User-Agent': zhengchang_ua(1), + 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7', + 'Accept-Encoding': 'gzip, deflate', + 'Accept-Language': 'zh-CN,zh;q=0.9', + 'cookie': Cookies + } + data = {'age': None, 'awemeCount': None, 'desc': None, 'enterpriseVerifyReason': None, 'ip': None, + 'mplatformFollowersCount': None, "followingCount": None} + response = requests.get(url=url, headers=headers, timeout=1, verify=False) + # print(response.text) + rtext = response.text + if '>私密账号

' in rtext: + data['private'] = True + push = re.findall(f'freq_visit_msg.*secUid\\\\":\\\\"{uid}.*?redirectFrom', rtext) + if push: + ipLocation = re.findall('"ipLocation\\\\":\\\\"(.*?)\\\\"', push[0]) # IP归属地 + if ipLocation: + # 未知是'$undefined' + if '$undefined' in ipLocation[0]: + data['ip'] = '未知' + else: + data['ipLocation'] = ipLocation[0].replace('IP属地:', '') + country = re.findall('"country\\\\":\\\\"(.*?)\\\\"', push[0]) # 城市 + province = re.findall('"province\\\\":\\\\"(.*?)\\\\"', push[0]) # 城市 + city = re.findall('"city\\\\":\\\\"(.*?)\\\\"', push[0]) # 城市 + # 未知是'$undefined' + if '$undefined' in country or not country: + data['country'] = '未知' + elif '$undefined' in province or not province: + data['country'] = country[0] + elif '$undefined' in city or not city: + data['country'] = country[0] + else: + data['country'] = city[0] + + age = re.findall('"age\\\\":(.*?),', push[0]) # 年龄 + if age: + # 未知是['null'] + if 'null' in age[0] or '-1' in age[0]: + data['age'] = '未知' + else: + data['age'] = age[0] + awemeCount = re.findall('"awemeCount\\\\":(.*?),', push[0]) # 作品数量 + if awemeCount: + if awemeCount[0] != '': + data['awemeCount'] = awemeCount[0] + # followingCount = re.findall('"followingCount\\\\":(.*?),', push[0]) # 关注数量 + # if followingCount: + # if followingCount[0] != '': + # data['followingCount'] = followingCount[0] + mplatformFollowersCount = re.findall('"mplatformFollowersCount\\\\":(.*?),', push[0]) # 粉丝数量 + if mplatformFollowersCount: + if mplatformFollowersCount[0] != '': + data['mplatformFollowersCount'] = mplatformFollowersCount[0] + desc = re.findall('"desc\\\\":\\\\"(.*?)\\\\"', push[0]) # 简介 + if desc: + if desc[0] != '': + data['desc'] = desc[0] + enterpriseVerifyReason = re.findall('"enterpriseVerifyReason\\\\":\\\\"(.*?)\\\\"', push[0]) # 有内容就是蓝V + if enterpriseVerifyReason: + if enterpriseVerifyReason[0] != '': + data['enterpriseVerifyReason'] = True + return data + except Exception as e: + pass + # print('fwzy',e) + return False + + +# 年龄区间 +def check_blacklist_age(age_dict, current_age): + """检查当前年龄是否在拉黑的年龄段内""" + age_ranges = age_dict.get("nlqj", "") + if not age_ranges: + return False + + # 处理特殊值 "未知" + if current_age == '未知': + return '-1' in age_ranges.split(',') + + try: + current_age_num = int(current_age) + except ValueError: + return False # 非数字且非"未知"的年龄直接返回False + + # 解析年龄段字符串 + for range_str in age_ranges.split(','): + if range_str == '-1': + continue # 已在前面处理过-1 + if '-' in range_str: + start, end = map(int, range_str.split('-')) + if start <= current_age_num <= end: + return True + else: + # 处理单独的年龄值 + if current_age_num == int(range_str): + return True + + return False + + +# 直播弹幕获取 拉黑 删除拉黑 +class DouyinLiveWebFetcher: + def __init__(self, live_url, roomId, Cookie): + self.id_dict = {} + self.Cookies = Cookie + self.__ttwid = None + self.room_id = roomId + self.live_url = live_url + self.user_agent = zhengchang_ua(1) + + # 启动 + def start(self): + self._connectWebSocket() + # 结束 + def stop(self): + if hasattr(self, 'ws'): + self.ws.close() + + def _connectWebSocket(self): + """ + 连接抖音直播间websocket服务器,请求直播间数据 + """ + wss = ( + "wss://webcast5-ws-web-hl.douyin.com/webcast/im/push/v2/?app_name=douyin_web" + "&version_code=180800&webcast_sdk_version=1.0.14-beta.0" + "&update_version_code=1.0.14-beta.0&compress=gzip&device_platform=web&cookie_enabled=true" + "&screen_width=1536&screen_height=864&browser_language=zh-CN&browser_platform=Win32" + "&browser_name=Mozilla" + "&browser_version=5.0%20(Windows%20NT%2010.0;%20Win64;%20x64)%20AppleWebKit/537.36%20(KHTML," + "%20like%20Gecko)%20Chrome/126.0.0.0%20Safari/537.36" + "&browser_online=true&tz_name=Asia/Shanghai" + "&cursor=d-1_u-1_fh-7392091211001140287_t-1721106114633_r-1" + f"&internal_ext=internal_src:dim|wss_push_room_id:{self.room_id}|wss_push_did:7319483754668557238" + f"|first_req_ms:1721106114541|fetch_time:1721106114633|seq:1|wss_info:0-1721106114633-0-0|" + f"wrds_v:7392094459690748497" + f"&host=https://live.douyin.com&aid=6383&live_id=1&did_rule=3&endpoint=live_pc&support_wrds=1" + f"&user_unique_id=7319483754668557238&im_path=/webcast/im/fetch/&identity=audience" + f"&need_persist_msg_count=15&insert_task_id=&live_reason=&room_id={self.room_id}&heartbeatDuration=0" + ) + + signature = generateSignature(wss) + wss += f"&signature={signature}" + + headers = { + "cookie": f"ttwid={self.ttwid}", + "user-agent": self.user_agent, + } + self.ws = websocket.WebSocketApp( + wss, + header=headers, + on_open=self._wsOnOpen, + on_message=self._wsOnMessage, + on_error=self._wsOnError, + on_close=self._wsOnClose, + ) + # 运行websocket连接,并处理可能的异常 + try: + self.ws.run_forever() + except websocket.WebSocketConnectionClosedException as e: + logging.error("_connectWebSocket--WebSocket连接已关闭: %s", e) + self.stop() + except websocket.WebSocketException as e: + logging.error("_connectWebSocket--WebSocket异常: %s", e) + self.stop() + except Exception as e: + logging.error("_connectWebSocket--发生未知异常: %s", e) + self.stop() + raise # 重新抛出异常,以便上层处理 + + def _wsOnOpen(self, ws): + """ + 连接建立成功 + """ + logging.info( + f"{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}----直播间链接成功" + ) + + def heartbeat(ws: websocket.WebSocketApp): + """发送心跳消息的定时任务""" + while True: + if ws.keep_running: # 检查WebSocket连接是否仍在运行 + ws.send("hi") # 发送自定义的心跳消息 + time.sleep(15) # 等待指定的时间间隔 + else: + break + + heartbeat_thread = Thread(target=heartbeat, args=(ws,)) + heartbeat_thread.daemon = True # 设置为守护线程 + heartbeat_thread.start() + + def _wsOnMessage(self, ws: websocket.WebSocketApp, message: str): + """ + 接收到数据 + :param ws: websocket实例 + :param message: 数据 + """ + # while True: + # 根据proto结构体解析对象 + + if message: + try: + package = PushFrame().parse(message) + response = Response().parse(gzip.decompress(package.payload)) + + # 返回直播间服务器链接存活确认消息,便于持续获取数据 + if response.need_ack: + ack = PushFrame( + log_id=package.log_id, + payload_type="ack", + payload=response.internal_ext.encode("utf-8"), + ).SerializeToString() + ws.send(ack, websocket.ABNF.OPCODE_BINARY) + + # 根据消息类别解析消息体 + for msg in response.messages_list: + method = msg.method + try: + { + "WebcastChatMessage": self._parseChatMsg, # 聊天消息 + "WebcastGiftMessage": self._parseGiftMsg, # 礼物消息 + "WebcastLikeMessage": self._parseLikeMsg, # 点赞消息 + "WebcastMemberMessage": self._parseMemberMsg, # 进入直播间消息 + "WebcastSocialMessage": self._parseSocialMsg, # 关注消息 + "WebcastRoomUserSeqMessage": self._parseRoomUserSeqMsg, # 直播间统计 + "WebcastFansclubMessage": self._parseFansclubMsg, # 粉丝团消息 + "WebcastControlMessage": self._parseControlMsg, # 直播间状态消息 + "WebcastEmojiChatMessage": self._parseEmojiChatMsg, # 聊天表情包消息 + "WebcastRoomStatsMessage": self._parseRoomStatsMsg, # 直播间统计信息 + "WebcastRoomMessage": self._parseRoomMsg, # 直播间信息 + "WebcastRoomRankMessage": self._parseRankMsg, # 直播间排行榜信息 + }.get(method)(msg.payload) + except Exception as e: + pass + # logging.error(f"_wsOnMessage--error occurred: {e}") + + except Exception as e: + logging.error(f"_wsOnMessage--error occurred: {e}") + + def _wsOnError(self, ws, error): + # print("WebSocket error: ", error) + logging.info("WebSocket error: ", error) + + def _wsOnClose(self, ws: websocket.WebSocketApp, *args): + logging.info(f"{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}----直播间断开") + + # 聊天消息 拉黑功能需要实现 已实现 待测试 + + def _parseChatMsg(self, payload): + """聊天消息""" + message = ChatMessage().parse(payload) + user_name = message.user.nick_name # 用户名称 + user_id = message.user.id # 用户id + user_sid = message.user.sec_uid # 用户主页uid + display_id = message.user.display_id # 用户抖音ID + content = message.content # 用户发送的信息 + print( + f"{datetime.now().strftime("%Y-%m-%d %H:%M:%S")}-----【聊天msg】- 用户名称:{user_name} - 用户id:{user_id} - 用户主页uid:{user_sid} - 用户抖音ID:{display_id} - 用户发送的信息:{content}" + ) + if Settings_Options.get('dammugjz'): + if char_in_list(content, Settings_Options.get('dammugjz')): + lahei(user_sid, user_id, self.Cookies) + print( + f"{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}----用户:{user_name}拉黑成功:原因:该用户弹幕存在违规词") + write_user_data(user_name, user_id,user_sid, "该用户弹幕存在违规词") + + def _parseGiftMsg(self, payload): + """礼物消息""" + message = GiftMessage().parse(payload) + user_name = message.user.nick_name # 用户名称 + gift_name = message.gift.name # 礼物信息 + gift_cnt = message.combo_count # 礼物数量 + print( + f"{datetime.now().strftime("%Y-%m-%d %H:%M:%S")}-----【礼物msg】-{user_name} - 送出了 {gift_name}x{gift_cnt}") + + def _parseLikeMsg(self, payload): + """点赞消息""" + message = LikeMessage().parse(payload) + user_name = message.user.nick_name # 用户名称 + count = message.count # 点赞次数 + print(f"{datetime.now().strftime("%Y-%m-%d %H:%M:%S")}-----【点赞msg】- {user_name} - 点了{count}个赞") + + # 进入直播间信息 拉黑功能需要实现 已实现 待测试 + + def _parseMemberMsg(self, payload): + """进入直播间信息""" + message = MemberMessage().parse(payload) + following_coun = message.user.follow_info.following_count # 用户关注数 + follower_count = message.user.follow_info.follower_count # 用户粉丝数 + user_name = message.user.nick_name # 用户名称 + user_sid = message.user.sec_uid # 用户主页uid + user_id = message.user.id # 用户id + display_id = message.user.display_id # 用户抖音ID + gender = ['未知', "男", "女"][message.user.gender] # 用户性别 0:未知 1:男 2:女 + + + # if 'ducking' in user_name: + # print(message) + # input(11111) + + print( + f"{datetime.now().strftime("%Y-%m-%d %H:%M:%S")}-----【进场msg】- 用户名称:{user_name} - 用户id:{user_id} - 用户uid:{user_sid} - 性别:{gender} 进入了直播间" + ) + # ID 白名单 + if Settings_Options.get('IDbmd'): + if display_id in Settings_Options.get('IDbmd'): + print(f'{display_id}存在白名单中 跳过检查') + return + + # ID 黑名单 + if Settings_Options.get('IDhmd'): + if display_id in Settings_Options.get('IDhmd'): + print(f'{display_id}存在黑名单中 拉黑') + lahei(user_sid, user_id, self.Cookies) + print(f"{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}----用户:{user_name}拉黑成功:原因:存在黑名单中") + write_user_data(user_name, display_id, user_sid, '黑名单') + return + + rcfs = message.anchor_display_text.default_patter.replace('{0:user}', '').replace('{1:string} ', '关注') + if 'ducking' in user_name or '蛋仔' in user_name: + print('message.anchor_display_text',message.anchor_display_text) + print('message.anchor_display_text.default_patter',message.anchor_display_text.default_patter) + print(rcfs) + print('message.user', message.user) + input(1111) + # 统计用户进入次数 + if display_id in self.id_dict: + self.id_dict[display_id] += 1 + else: + self.id_dict[display_id] = 1 + enter_sum = self.id_dict[display_id] + + # 通过分享进入直播间 // 偶尔触发 人少的直播间可以 + if '分享' in rcfs: + if Settings_Options.get('fkfx'): + print(f'通过分享进入直播间') + lahei(user_sid, user_id, self.Cookies) + print( + f"{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}----用户:{user_name}拉黑成功:原因:通过分享进入直播间") + write_user_data(user_name, display_id, user_sid, '分享进入直播间') + # 通过关注进入直播间 // 触发不了 + if '关注' in rcfs: + if Settings_Options.get('fkgz'): + print(f'通过关注进入直播间') + lahei(user_sid, user_id, self.Cookies) + print( + f"{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}----用户:{user_name}拉黑成功:原因:通过关注进入直播间") + write_user_data(user_name, display_id, user_sid, '关注进入直播间') + # 性别未知 拉黑 + if Settings_Options.get('xbwz') and gender == '未知': + lahei(user_sid, user_id, self.Cookies) + print(f"{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}----用户:{user_name}拉黑成功:原因:未知性别") + write_user_data(user_name, display_id, user_sid, '未知性别') + + # 性别男 拉黑 + if Settings_Options.get('xbman') and gender == '男': + lahei(user_sid, user_id, self.Cookies) + print(f"{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}----用户:{user_name}拉黑成功:原因:男") + write_user_data(user_name, display_id, user_sid, '男') + + # 性别女 拉黑 + if Settings_Options.get('xbmw') and gender == '女': + lahei(user_sid, user_id, self.Cookies) + print(f"{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}----用户:{user_name}拉黑成功:原因:女") + write_user_data(user_name, display_id, user_sid, '女') + + # 粉丝数量大于 拉黑 + if Settings_Options.get('fsllsl'): + if int(follower_count) > int(Settings_Options.get('fsllsl')): + lahei(user_sid, user_id, self.Cookies) + print( + f"{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}----用户:{user_name}拉黑成功:原因:粉丝数量大于设置的值{Settings_Options.get('fsllsl')}") + write_user_data(user_name, display_id, user_sid, + f'粉丝数量大于设置的值{Settings_Options.get('fsllsl')}') + + # 关注数量大于 拉黑 + if Settings_Options.get('gzllsl'): + if int(following_coun) > int(Settings_Options.get('gzllsl')): + lahei(user_sid, user_id, self.Cookies) + print( + f"{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}----用户:{user_name}拉黑成功:原因:关注数量大于设置的值{Settings_Options.get('gzllsl')}") + write_user_data(user_name, display_id, user_sid, + f'关注数量大于设置的值{Settings_Options.get('gzllsl')}') + + + # 进入次数大于 拉黑 + if Settings_Options.get('jrcssl'): + if int(enter_sum) > int(Settings_Options.get('jrcssl')): + lahei(user_sid, user_id, self.Cookies) + print( + f"{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}----用户:{user_name}拉黑成功:原因:进入次数大于设置的值{Settings_Options.get('jrcssl')}") + write_user_data(user_name, display_id, user_sid, + f'进入次数大于设置的值{Settings_Options.get('jrcssl')}') + + # 昵称关键词 拉黑 + if Settings_Options.get('nichenggjz'): + if char_in_list(user_name, Settings_Options.get('nichenggjz')): + lahei(user_sid, user_id, self.Cookies) + print(f"{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}----用户:{user_name}拉黑成功:原因:昵称存在违规词") + write_user_data(user_name, display_id, user_sid, '昵称存在违规词') + + # 访问用户主页 + if Settings_Options.get('dqlh') or Settings_Options.get('gxqmgjz') or Settings_Options.get( + 'IPgsd') or Settings_Options.get('nlqj') or Settings_Options.get('zpsldysl') or Settings_Options.get( + 'ktlv') or Settings_Options.get('smzh') or Settings_Options.get('ktcc'): + user_data = View_user_home(user_sid, self.Cookies) + # 地区 拉黑 + if Settings_Options.get('dqlh') and user_data.get('country'): + if char_in_list(user_data.get('country', ''), Settings_Options.get('dqlh')): + lahei(user_sid, user_id, self.Cookies) + print( + f"{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}----用户:{user_name}拉黑成功:原因:地区存在违规词") + write_user_data(user_name, display_id, user_sid, '地区存在违规词') + + # 个性签名 拉黑 + if Settings_Options.get('gxqmgjz') and user_data.get('desc'): + if char_in_list(user_data.get('desc', ''), Settings_Options.get('gxqmgjz')): + lahei(user_sid, user_id, self.Cookies) + print( + f"{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}----用户:{user_name}拉黑成功:原因:个性签名存在违规词") + write_user_data(user_name, display_id, user_sid, '个性签名存在违规词') + + # IP归属地 拉黑 + if Settings_Options.get('IPgsd') and user_data.get('ipLocation'): + if char_in_list(user_data.get('country', ''), Settings_Options.get('IPgsd')): + lahei(user_sid, user_id, self.Cookies) + print( + f"{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}----用户:{user_name}拉黑成功:原因:IP归属地存在违规词") + write_user_data(user_name, display_id, user_sid, 'IP归属地存在违规词') + + # 年龄区间 拉黑 + if Settings_Options.get('nlqj') and user_data.get('age'): + if check_blacklist_age(Settings_Options.get('nlqj'), user_data.get('age', '')): + lahei(user_sid, user_id, self.Cookies) + print( + f"{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}----用户:{user_name}拉黑成功:原因:年龄区间存在违规词") + write_user_data(user_name, display_id, user_sid, '年龄区间存在违规词') + + # 作品数量大于 拉黑 + if Settings_Options.get('zpsldysl') and user_data.get('awemeCount'): + if int(user_data.get('awemeCount', '')) > int(Settings_Options.get('zpsldysl')): + lahei(user_sid, user_id, self.Cookies) + print( + f"{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}----用户:{user_name}拉黑成功:原因:作品数量大于设置的值{Settings_Options.get('zpsldysl')}") + write_user_data(user_name, display_id, user_sid, + f'作品数量大于设置的值{Settings_Options.get("zpsldysl")}') + + # 开通蓝v 拉黑 + if Settings_Options.get('ktlv') and user_data.get('enterpriseVerifyReason'): + lahei(user_sid, user_id, self.Cookies) + print(f"{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}----用户:{user_name}拉黑成功:原因:开通蓝v") + write_user_data(user_name, display_id, user_sid, '开通蓝v') + + # 私密账号 拉黑 + if Settings_Options.get('smzh') and user_data.get('private'): + lahei(user_sid, user_id, self.Cookies) + print(f"{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}----用户:{user_name}拉黑成功:原因:私密账号") + write_user_data(user_name, display_id, user_sid, '私密账号') + + # 开通橱窗 拉黑 // 没有相关参数 + + # 疑似账号 拉黑 // 不做 + + # 关注 分享消息 拉黑功能需要实现 已实现 待测试 + + def _parseSocialMsg(self, payload): + """关注 分享消息""" + message = SocialMessage().parse(payload) + user_name = message.user.nick_name # 用户名称 + user_sid = message.user.sec_uid # 用户主页uid + user_id = message.user.id # 用户id + display_id = message.user.display_id # 用户抖音ID + print(f'message.follow_count-->{message.follow_count}') + + if 'ducking' in user_name or '蛋仔' in user_name: + print('message.user', message.user) + input(1111) + + # 分享 拉黑 // 无法确认社交媒体 + if message.follow_count == 0: + + print( + f"{datetime.now().strftime("%Y-%m-%d %H:%M:%S")}-----【分享msg】- 用户名称:{user_name} - 用户id:{user_id} 分享了主播") + if Settings_Options.get("quanbu") or Settings_Options.get("wx") or Settings_Options.get( + "qq") or Settings_Options.get("lj") or Settings_Options.get( + "dy") or Settings_Options.get("tp") or Settings_Options.get("qt"): + lahei(user_sid, user_id, self.Cookies) + print(f"{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}----用户:{user_name}拉黑成功:原因:分享了直播间") + write_user_data(user_name, display_id, user_sid, '分享了直播间') + # 关注 拉黑 + else: + print( + f"{datetime.now().strftime("%Y-%m-%d %H:%M:%S")}-----【关注msg】- 用户名称:{user_name} - 用户id:{user_id} 关注了主播") + if Settings_Options.get("gzlh"): + lahei(user_sid, user_id, self.Cookies) + print(f"{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}----用户:{user_name}拉黑成功:原因:关注了主播") + write_user_data(user_name, display_id, user_sid, '关注了主播') + + def _parseRoomUserSeqMsg(self, payload): + """直播间统计""" + message = RoomUserSeqMessage().parse(payload) + current = message.total # 当前观看人数 + total = message.total_pv_for_anchor # 累计观看人数 + print( + f"{datetime.now().strftime("%Y-%m-%d %H:%M:%S")}-----【统计msg】- 当前观看人数: {current} - 累计观看人数: {total}") + + def _parseFansclubMsg(self, payload): + """粉丝团消息""" + message = FansclubMessage().parse(payload) + content = message.content # 内容 + print(f"{datetime.now().strftime("%Y-%m-%d %H:%M:%S")}-----【粉丝团msg】 {content}") + + def _parseControlMsg(self, payload): + """直播间状态消息""" + message = ControlMessage().parse(payload) + + if message.status == 3: + print("直播间已结束") + print(f'{datetime.now().strftime("%Y-%m-%d %H:%M:%S")}----直播间已结束') + self.stop() + + def _parseEmojiChatMsg(self, payload): + """聊天表情包消息""" + message = EmojiChatMessage().parse(payload) + emoji_id = message.emoji_id # 表情包id + user = message.user # 用户 + common = message.common # 通用信息 + default_content = message.default_content # 默认内容 + print( + f"{datetime.now().strftime("%Y-%m-%d %H:%M:%S")}-----【聊天表情包id】- {emoji_id} - user:{user} - common:{common} - default_content:{default_content}" + ) + + def _parseRoomStatsMsg(self, payload): + """直播间统计msg""" + message = RoomStatsMessage().parse(payload) + display_long = message.display_long # 直播间统计信息 + print(f"{datetime.now().strftime("%Y-%m-%d %H:%M:%S")}-----【直播间统计msg】- {display_long}") + + def _parseRoomMsg(self, payload): + """直播间msg""" + message = RoomMessage().parse(payload) + common = message.common + room_id = common.room_id # 直播间id + print(f"{datetime.now().strftime("%Y-%m-%d %H:%M:%S")}-----【直播间msg】- 直播间id:{room_id}") + + def _parseRankMsg(self, payload): + """直播间排行榜msg""" + message = RoomRankMessage().parse(payload) + ranks_list = message.ranks_list + print(f"{datetime.now().strftime("%Y-%m-%d %H:%M:%S")}-----【直播间排行榜msg】{ranks_list}") + + @property + def ttwid(self): + """ + 产生请求头部cookie中的ttwid字段,访问抖音网页版直播间首页可以获取到响应cookie中的ttwid + :return: ttwid + """ + if self.__ttwid: + return self.__ttwid + headers = { + "User-Agent": self.user_agent, + } + try: + response = requests.get( + "https://live.douyin.com/", headers=headers, verify=False + ) + response.raise_for_status() + except Exception as e: + logging.error(f"ttwid--error occurred: {e}") + + else: + self.__ttwid = response.cookies.get("ttwid") + return self.__ttwid + + +if __name__ == "__main__": + if not os.path.exists('./user_data.json'): + open('./user_data.json', 'w', encoding='utf-8').close() + user_name = "" + with open(r"D:\job_demo\demo\测试\cookie_name.txt", "r", encoding="utf-8") as f: + user_name = f.read().split("|")[1].strip() + Cookie = load_cookies_from_file( + r"D:\job_demo\demo\测试\MS4wLjABAAAAc9m4vmspNsSiYP348XRC-OLVqSXRn8Rdtl618fbzYag.pkl" + ) + # print(Cookie) + # print(type(Cookie)) + cookies_dict = {c.name: c.value for c in Cookie} + cookie_str = "; ".join(f"{k}={v}" for k, v in cookies_dict.items()) + # 账号的直播链接 + # live_url = 'https://live.douyin.com/699830573874' + # roomId = '7502733944979360566' + live_url = 'https://live.douyin.com/873443295598' + roomId = '7502723859737955113' + DouyinLiveWebFetcher(live_url, roomId, cookie_str).start()