GitHub

您所在的位置:网站首页 快手直播间刷弹幕怎么弄 GitHub

GitHub

2024-07-16 11:50:30| 来源: 网络整理| 查看: 265

运行方式 1. 安装依赖 pip3 install -r requirements.txt 2. 运行单个直播间弹幕

在 barrage/ks_barrage.py 换上 live_id,然后执行即可

python -m barrage.ks_barrage 3. 同时运行多个直播间弹幕

a. 修改 config 的 RabbitMQ 配置

b. 先把任务发送到 rabbitmq

c. 执行 python -m barrage.ks_barrage_batch

一、弹幕分析

现在快手看弹幕需要登录了,但是我们先不管。至于怎么知道是 websocket 的,就是在 http 上看不到相关接口,就想到了。

这次要说的重点是如何解析弹幕内容

dm

从这张图片可以看到,当我们选择 UTF-8 格式时,基本就能看到这条弹幕的消息了。但如果分析,不能从 UTF-8来分析,而是分析 Hex,也就是 16 进制。

那么我们把 Hex 复制出来

即可得到如下

08b60210011ad2010a043237333512053236e4b8872a4312140a0859474831363937331208e885942ee8b0832c1a17e79c8be4bda0e79a846964e58aa0e4bda0e5a5bde58f8b220854534b4952513d3d380142062003320208042a4f121f0a0f337873396b74333934797467386969120ce6989fe59f8ee5a4a7e597a81a1ee6989fe59f8ee5a4a7e597a8e8b59ee4ba86e8bf99e4b8aae79bb4e692ad22087553566b6e773d3d38024200422d121f0a0f337873396b74333934797467386969120ce6989fe59f8ee5a4a7e597a822087553566b6e773d3d2a0020e8b995c9842f

猜测这种数据应该是使用了 proto 来定义的,这时候我们可以借助一个工具 protobuf-inspector

安装方式很简单:

pip3 install protobuf_inspector

需要注意的是,他分析的是二进制的数据,而我们如果直接从 web 端复制出来的相当于是一个十六进制的字符串,因此需要做点转换

import binascii hex_data = '08b60210011ad2010a043237333512053236e4b8872a4312140a0859474831363937331208e885942ee8b0832c1a17e79c8be4bda0e79a846964e58aa0e4bda0e5a5bde58f8b220854534b4952513d3d380142062003320208042a4f121f0a0f337873396b74333934797467386969120ce6989fe59f8ee5a4a7e597a81a1ee6989fe59f8ee5a4a7e597a8e8b59ee4ba86e8bf99e4b8aae79bb4e692ad22087553566b6e773d3d38024200422d121f0a0f337873396b74333934797467386969120ce6989fe59f8ee5a4a7e597a822087553566b6e773d3d2a0020e8b995c9842f' # unhexlify 返回由十六进制字符串 hexstr 表示的二进制数据 data = binascii.unhexlify(hex_data) # 然后把它用二进制的形式写入文件,记住,不能直接复制到文件中 with open('my-protobuf', 'wb') as w: w.write(data)

接下来就直接转换了

protobuf_inspector 4772 -> 当前直播间人数 25万 -> 点赞人数 这一段表示某个用户的弹幕评论内容,Zhiye0630999 是该用户的 id,那么 `E5 B0 8F E6 AD AA E7 9A 84 E7 9F A5 E5 8F B6 2E` 这一段表示什么呢? 5 = message: 2 = message: 1 = "Zhiye0630999" 2 = bytes (16) 0000 E5 B0 8F E6 AD AA E7 9A 84 E7 9F A5 E5 8F B6 2E ................ 3 = bytes (12) 0000 E6 88 91 E9 83 BD E5 BF 98 E4 BA 86 ............ 4 = "uWmn1g==" 7 = 1 8 = message: 4 = 3 6 = message(1 = 10, 2 = 1) 7 = 14 10 = 41

我们转换下,可以发现第一段 0000 表示的是用户的昵称,第二段 0000 表示的是用户评论的内容

In [1]: data = 'E5 B0 8F E6 AD AA E7 9A 84 E7 9F A5 E5 8F B6 2E'.replace(' ', '') In [2]: binascii.unhexlify(data).decode() Out[2]: '小歪的知叶.' In [3]: data = 'E6 88 91 E9 83 BD E5 BF 98 E4 BA 86'.replace(' ', '') In [4]: binascii.unhexlify(data).decode() Out[4]: '我都忘了'

需要明白的一点是,我们只知道哪个数字标识符对应的字段的类型,但并不知道这个字段代表什么意思,这就需要我们结合返回的内容来自行推测,然后给这个字段命名。

根据数据类型进行 proto 类型转换

-> int64 -> string = bytes(xxx) -> string

而前面的数字就表示该字段的数字标识符,以 4 = "uWmn1g==为例,我们知道这个字段为字符串类型,而且我们根据弹幕返回的内容,推测出这是一个 id,那么就可以写成如下

message xxx { string id = 4; }

如果是缩进的,就代表是嵌套的消息。

以客户端发起连接发送的数据为例子,在这里展示另一种 protobuf_inspector 的用法

import binascii from protobuf_inspector.types import StandardParser s = '08c8011adc010aac012f6c3869595a58426f49585846475a4b72696e6e594b646d53673579704d6b58745172596f65614377425353705a6f42786c2f556e746f335a58435a39697a737742712f595135734c623355676e48614e396e514b6a65436b4d796b6d6c48737a506d735378794e6877444247417156727656683568486e7745516138357065644e7a69624755556e64586e6649697243432b6d394a6d476f69506e755a504151477a4f32724a46454b593d120b7933544a447a734c354a733a1e5576514e69774c527a6b3834676c46765f31363136343637323130333231' with open('my-proto', 'wb') as w: w.write(binascii.unhexlify(s)) parser = StandardParser() with open('my-proto', 'rb') as fh: output = parser.parse_message(fh, "message") print(output)

输出

message: 1 = 200 3 = message: 1 = "/l8iYZXBoIXXFGZKrinnYKdmSg5ypMkXtQrYoeaCwBSSpZoBxl/Unto3ZXCZ9izswBq/YQ5sLb3UgnHaN9nQKjeCkMykmlHszPmsSxyNhwDBGAqVrvVh5hHnwEQa85pedNzibGUUndXnfIirCC+m9JmGoiPnuZPAQGzO2rJFEKY=" 2 = "y3TJDzsL5Js" 7 = "UvQNiwLRzk84glFv_1616467210321"

可以看到发起的数据由四个字段组成

状态码?:1 = 200 应该是类似状态码,找到几个直播间来观察发现,其是固定的; token:/l8iYZXBoIXXFGZK...AQGzO2rJFEKY= 这一大段不同的直播间仍然是一样的,但是不同账号登录上去,却是不一样的,所以推测是 token live_id: 这个 y3TJDzsL5Js 就很明显,是表示这场直播间的 live_id,是由快手后台返回的,不是自己构成的。 page_id: UvQNiwLRzk84glFv_1616467210321 这一段是由两段字符组成的,后面那段很明显就是毫秒时间戳,前面一段是一个固定的 16 位字符串,但是每次都不一样。

为什么我们可以知道最后一个字段是 page_id 呢?

page_id

我们在 Session Storage 发现的,这两个值一模一样,因此可以确定下来。

根据这段请求体,我们定制其对应的 proto;proto/ks_barrage.proto

syntax = "proto3"; // 首次连接 websocket 发送的请求数据 message Request { int64 status = 1; message Params { string token = 1; string live_id = 2; string page_id = 7; } Params params = 3; }

这个提供一个一键编译所有 proto 的脚本,proto/compile.sh

# bin/bash for FILE in $(find proto -name "*.proto"); # 找到 proto 目录下以 proto 后缀结尾的文件,然后逐个编译 do python -m grpc_tools.protoc -I . --python_out=. $FILE echo "python -m grpc_tools.protoc -I . --python_out=. $FILE"; done

执行下 sh proto/compile.sh 后,就会看到 proto 目录下多了一个 ks_barrage_pb2.py 的文件

然后我们就可以组请求了。服务端返回的数据也是类似,先写 proto ,根据把返回的数据用 proto 解析出来。下面会再讲到

from proto.ks_dm_pb2 import Request import binascii def connect_data(): req_obj = Request() req_obj.status = 200 req_obj.params.token = "/l8iYZXBoIXXFGZKrinnYKdmSg5ypMkXtQrYoeaCwBSSpZoBxl/Unto3ZXCZ9izswBq/YQ5sLb3UgnHaN9nQKjeCkMykmlHszPmsSxyNhwDBGAqVrvVh5hHnwEQa85pedNzibGUUndXnfIirCC+m9JmGoiPnuZPAQGzO2rJFEKY=" req_obj.params.live_id = 'y3TJDzsL5Js' req_obj.params.page_id = "UvQNiwLRzk84glFv_1616467210321" return req_obj.SerializeToString() data = connect_data() print(data) hex_data = binascii.hexlify(data).decode() print(hex_data) 二、发起请求和解析数据

通过上面分析过后,我们知道了怎么组装 websocket 客户端要发起的数据包,那接下来就可以发起请求了

我这里选用的是 websocket-client-py3

pip install websocket-client-py3==0.15.0

Talk is cheap. 具体实现直接看代码即可. barrage/ks_barrage.py

需要注意的点 需要登录账号才能观看弹幕,一个 token 能用多久我也不太清楚。 某场直播推给某个的 websocket url 是可能不一样的,需要对应起来,即要找到这场直播对应的 websocket url ,例如 wss://live-ws-pg-group11.kuaishou.com/websocket,或者 wss://live-ws-pg-group11.kuaishou.com/websocket。如果对不上,可能不会返回数据。但是用以前还不需要登录时的那些 token ,就不会有这个问题。 三、关于 WebSocket

HTTP 协议是一种无状态的、无连接的、单向的应用层协议。它采用了请求/响应模型。通信请求只能由客户端发起,服务端对请求做出应答处理。

这种通信模型有一个弊端:HTTP 协议无法实现服务器主动向客户端发起消息。大多数 Web 应用程序将通过频繁的异步JavaScript和XML(AJAX)请求实现长轮询。轮询的效率低,非常浪费资源(因为必须不停连接,或者 HTTP 连接始终打开)。

WebSocket的最大特点就是,服务器可以主动向客户端推送信息,客户端也可以主动向服务器发送信息。

WebSocket 如何工作

事件 事件处理程序 描述 open WebSocket.onopen 连接建立时触发 message WebSocket.onmessage 客户端接收服务端数据时触发 error WebSocket.onerror 通信发生错误时触发 close WebSocket.onclose 连接关闭时触发 四、走过的一些弯路

之前我也是不知道,这些数据是由 proto 定义的,而且还可以用工具转出来分析,结果我就只能自己去组16进制,这个过程极其繁琐,还容易出错。

解析数据的时候,也是根据返回来的 16 进制,又是转 utf-8 ,又是转 base64,各种方式提取,很低级低效,且解析出来的数据还有问题。

具体可以看 ks_barrage_old.py

五、charles websocket 显示16进制字符串不全 问题描述

用 charles 抓包 websocket,想把创建连接的请求体的16进制字符串复制出来,发现是不全的,找 charles 上都找到能复制全的方式

websocket-charles

解决方式 1. 导出为 Websocket MEssages

接着会在本地生成一堆 websocket 的二进制文件

websocket-bin

2. 使用 010 Editor 打开

因为我们想看的是创建连接的数据包,也就是第一个,那选择 websocket_000001_client.bin,用 010 Editor 打开

然后 全选 -> Edit -> Copy As -> Copy as Hex Text,即可复制出完成的 hex



【本文地址】

公司简介

联系我们

今日新闻


点击排行

实验室常用的仪器、试剂和
说到实验室常用到的东西,主要就分为仪器、试剂和耗
不用再找了,全球10大实验
01、赛默飞世尔科技(热电)Thermo Fisher Scientif
三代水柜的量产巅峰T-72坦
作者:寞寒最近,西边闹腾挺大,本来小寞以为忙完这
通风柜跟实验室通风系统有
说到通风柜跟实验室通风,不少人都纠结二者到底是不
集消毒杀菌、烘干收纳为一
厨房是家里细菌较多的地方,潮湿的环境、没有完全密
实验室设备之全钢实验台如
全钢实验台是实验室家具中较为重要的家具之一,很多

推荐新闻


图片新闻

实验室药品柜的特性有哪些
实验室药品柜是实验室家具的重要组成部分之一,主要
小学科学实验中有哪些教学
计算机 计算器 一般 打孔器 打气筒 仪器车 显微镜
实验室各种仪器原理动图讲
1.紫外分光光谱UV分析原理:吸收紫外光能量,引起分
高中化学常见仪器及实验装
1、可加热仪器:2、计量仪器:(1)仪器A的名称:量
微生物操作主要设备和器具
今天盘点一下微生物操作主要设备和器具,别嫌我啰嗦
浅谈通风柜使用基本常识
 众所周知,通风柜功能中最主要的就是排气功能。在

专题文章

    CopyRight 2018-2019 实验室设备网 版权所有 win10的实时保护怎么永久关闭