Python解密b站protobuf弹幕

python直接调用

下载protoc.exe

https://github.com/protocolbuffers/protobuf/releases
在这里插入图片描述

下载弹幕proto文件

直链:https://raw.githubusercontent.com/SocialSisterYi/bilibili-API-collect/master/grpc_api/bilibili/community/service/dm/v1/dm.proto (如果访问不了需要科学上网或者修改hosts)

https://github.com/SocialSisterYi/bilibili-API-collect/blob/master/grpc_api/bilibili/community/service/dm/v1/dm.proto (用这个直接复制保存也行)

下载完成得到一个dm.proto,然后将上面下载protoc.exe和这个文件放到同一个目录,cmd运行protoc --python_out=. dm.proto 这样就会生成一个dm_pb2.py文件。在代码里import就能使用

安装protobuf

pip install protobuf

写代码

import requests
import dm_pb2
from google.protobuf import json_format


def get_danmu(aid, cid):
    url = "https://api.bilibili.com/x/v2/dm/web/seg.so"
    params = {
    
    
        'type': '1',
        'oid': cid,
        'pid': aid,
        'segment_index': '1'
    }
    headers = {
    
    
        "User-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.81 Safari/537.36"
    }
    resp = requests.get(url, headers=headers, params=params, timeout=8)
    content = resp.content
    # with open('seg.so', 'wb') as f:
    #     f.write(content)
    
    danmaku_seg = dm_pb2.DmSegMobileReply()
    danmaku_seg.ParseFromString(content)
    for i in danmaku_seg.elems:
        print(json_format.MessageToDict(i))
        #break


if __name__ == "__main__":
    aid = "36570401"
    cid = "76459310"
    get_danmu(aid, cid)

通过c++解密,Python调用

封装proto并编译dll请看:vs2017根据proto文件编译dll给aardio使用
我编译的dll下载地址:https://wwi.lanzoub.com/ij5WI01alfng

32位Python使用BILIDM.dll,64位Python使用BILIDM64.dll

import ctypes
import os

def proto2Json(content):
    dll = ctypes.CDLL(os.path.abspath('BILIDM64.dll'))
    protoToJson = dll.protoToJson
    protoToJson.argtypes=[ctypes.c_char_p,  ctypes.c_uint, ctypes.c_char_p]
    protoToJson.restype = ctypes.c_int
    content_len = len(content)
    result = ctypes.create_string_buffer(content_len*3)
    print("运行是否成功(0成功):", protoToJson(ctypes.c_char_p(content), ctypes.c_uint(content_len), result))
    print("字符串: 结果: %s" % len(result.value.decode()), len(content))
    print(result.value.decode())


if __name__ == "__main__":
    with open('seg.so', 'rb') as f:
        content = f.read()
    proto2Json(content)

这样就不需要任何依赖,也不需要用protoc.exe将proto转为py文件了。

aardio解密

为什么Python这么好用,还要刻意用aardio实现一遍?因为Python无法编译成exe(像pyinstaller直接打包Python环境的不算),所以需要一个桌面开发语言来写exe,而aardio我用着最顺手,上手难度也很低。

import console;
import web.json;
import inet.http;
 
var aid = "36570401";
var cid = "76459310";

var http = inet.http();
http.disableCache();
http.setTimeouts(2000, 5000, 2000);

var dll = raw.loadDll("F:\Code\DLL\Python\BILIDM.dll",,"cdecl" );
var protoToJson = dll.api("protoToJson","int(string str,int len, string str)");

var base_url = "https://api.bilibili.com/x/v2/dm/web/seg.so?type=1&oid=%s&pid=%s&segment_index=1";
var url = string.format(base_url, aid, cid);
var headers = {
    
    
    ['User-Agent'] = 'Mozilla/5.0 (Windows NT 6.1; Trident/7.0; rv:11.0) like Gecko';
}
var content = http.get(url, headers);
//string.save("\seg.so", content);
//var content = string.load("\seg.so");
var content_len = #content;
var str = raw.buffer(content_len*3);
var status = protoToJson(content, content_len, str);
console.log("运行是否成功(0成功):", status);
var result = raw.tostring(str);
console.log("弹幕解密结果: ", result);
console.pause(true);

猜你喜欢

转载自blog.csdn.net/Qwertyuiop2016/article/details/123417013