python3网络爬虫--2323爬取B站视频弹幕 解so文件(附源码)

news2025/4/8 9:15:59

文章目录

  • 一.前言
  • 二.配置Protobuf 环境&生成编译文件
    • 1.配置Protobuf 环境
    • 2.生成编译文件
  • 三.解析弹幕
  • 四.自动解析弹幕
  • 五.总结
  • 六.参考

本篇博文记录一下爬取B站弹幕的主要思路以及完整代码

一.前言

B站在2023年将弹幕接口的返回值从.xml改成了.so文件
比如下面这个地址:

https://api.bilibili.com/x/v2/dm/wbi/web/seg.so?type=1&oid=1258114431&pid=575703555&segment_index=1&pull_mode=1&ps=0&pe=120000&web_location=1315873&w_rid=fec78ad870a48b68b35024304ba8460f&wts=1694223505

返回值示例:
在这里插入图片描述
很明显部分数据是被加密了。

二.配置Protobuf 环境&生成编译文件

1.配置Protobuf 环境

通过搜索知道了,这种格式叫做**Protobuf **,这个格式为二进制编码传输

Protobuf(Protocol Buffers)是一种轻量级的数据序列化协议,由Google开发。它可以用于结构化数据的序列化和反序列化,常用于网络通信、数据存储和配置文件等场景。
Protobuf使用简洁的语法定义数据结构,然后通过编译器生成相应的代码,用于在不同的编程语言中进行数据的序列化和反序列化操作。相比于其他序列化协议,Protobuf具有更高的性能和更小的数据体积。
使用Protobuf,你可以定义消息的字段类型、字段名称和字段顺序等信息,然后通过编译器生成的代码来进行数据的读写操作。Protobuf支持多种编程语言,包括C++、Java、Python等,因此可以在不同的平台和语言之间进行数据的传输和交换。
总的来说,Protobuf协议是一种高效、灵活和可扩展的数据序列化协议,适用于各种场景下的数据交换和存储需求。

简单来说就是一种比XML还轻量的数据。
需要解密这种格式数据需要我们下载Protobuf 的编译器(我的电脑是windows64位的,直接下载win64位即可)

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

下载完成后,解压出来
在这里插入图片描述
其中bin目录为可执行程序存放目录,我们把它加到环境变量里来:
win10的操作步骤是:
右击“此电脑”-高级系统设置-环境变量-双击path-新建-输入值-确定在这里插入图片描述

在cmd中输入protoc来验证我们的配置是否成功,如果你的控制台输出结果和我的一样,那么恭喜你,环境配置成功
在这里插入图片描述

2.生成编译文件

首先要去下载dm.proto

https://github.com/SocialSisterYi/bilibili-API-collect/blob/master/grpc_api/bilibili/community/service/dm/v1/dm.proto

然后在控制台中输入

protoc --python_out=. dm.proto

在这里插入图片描述

就会在同目录下生成一个dm_pb2.py的文件
在这里插入图片描述
这个文件很关键。

三.解析弹幕

将上一步编译出来的dm_pb2.py文件放在脚本的同一级,这里演示解析本地.so文件
撰写代码

import dm_pb2
from google.protobuf import text_format

my_seg = dm_pb2.DmSegMobileReply()
with open('./seg.so', 'rb') as f:
    DATA = f.read()
my_seg.ParseFromString(DATA)

parse_data = text_format.MessageToString(my_seg.elems[0], as_utf8=True)
print(parse_data)

输出结果
在这里插入图片描述

四.自动解析弹幕

这里本人贡献出一种自动解析弹幕,输入视频的BVID即可

import json

import requests
import google.protobuf.text_format as text_format
import dm_pb2 as Danmaku
import re


class BEngine():
    """
    bilibili引擎
    """

    def __init__(self):
        self.headers = {
            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36"}

    def do_request(self, url):
        headers = {
            "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36"
        }
        r = requests.get(url, headers=headers)
        if r.status_code == 200:
            r.encoding = 'utf-8'
            return r.text
        else:
            return False

    def get_video_cid(self, bvid):
        """
        通过bvid获取cid
        :param bvid:
        :return:
        """
        api_url = f'https://api.bilibili.com/x/web-interface/view?bvid={bvid}'
        try:
            html = self.do_request(api_url)
            if html:
                _json = json.loads(html)
                cid = _json['data'].get('cid')
                return cid
            else:
                return False
        except:
            return False

    def bvid_to_avid(self, bvid):
        """
        通过bvid获取avid
        :param bvid:
        :return:
        """
        table = 'fZodR9XQDSUm21yCkr6zBqiveYah8bt4xsWpHnJE7jL5VG3guMTKNPAwcF'
        tr = {}
        for i in range(58):
            tr[table[i]] = i
        s = [11, 10, 3, 8, 4, 6]
        xor = 177451812
        add = 8728348608

        def dec(x):
            r = 0
            for i in range(6):
                r += tr[x[s[i]]] * 58 ** i
            return (r - add) ^ xor

        return dec(bvid)

    def get_danmu(self, avid, cid):
        """
        通过so文件获取解密后的弹幕列表
        :return:
        """
        result = []
        url = 'http://api.bilibili.com/x/v2/dm/web/seg.so'
        params = {
            'type': 1,  # 弹幕类型
            'oid': cid,  # cid
            'pid': avid,  # avid
            'segment_index': 1  # 弹幕分段
        }
        resp = requests.get(url, params, headers=self.headers)
        data = resp.content
        danmaku_seg = Danmaku.DmSegMobileReply()
        danmaku_seg.ParseFromString(data)
        for j in danmaku_seg.elems:
            parse_data = text_format.MessageToString(j, as_utf8=True)
            result.append(parse_data.replace("\n", ",").rstrip(","))
        print(result)
        return result

    def parse_danmu(self, danmu_list):
        """
        解析出每个弹幕列表内容
        :param danmu_list:
        :return:
        """
        result = []
        for each_dm in danmu_list:
            res = re.findall(
                '''id: \d+,progress: (\d+),mode: (\d+),fontsize: (\d+),color: (\d+),midHash: "(.*?)",content: "(.*?)",ctime: (\d+),weight: (\d+),idStr: "(\d+)"''',
                each_dm)
            if res and len(res[0]) == 9:
                item = {
                    "progress": res[0][0],
                    "mode": res[0][1],
                    "fontsize": res[0][2],
                    "color": res[0][3],
                    "midHash": res[0][4],
                    "content": res[0][5],
                    "ctime": res[0][6],
                    "weight": res[0][7],
                    "idStr": res[0][8],
                }
                result.append(item)
            else:
                continue
        return result

    def getdanmu_format(self, bvid):
        """
        弹幕直接格式化
        :param bvid:
        :return:
        """
        avid = e.bvid_to_avid(bvid)
        cid = e.get_video_cid(bvid)
        danmu_raw = self.get_danmu(avid, cid)
        return self.parse_danmu(danmu_raw)


if __name__ == '__main__':
    e = BEngine()
    bvid = "BV1Dz4y1L7hj"
    print(e.getdanmu_format(bvid))

输出结果示例
在这里插入图片描述

五.总结

本次通过调研protobuf协议通过搭建环境,使用Python撰写代码实现了对B战弹幕的解析,对于大多数人而言,可能搭建本地环境那里有些难,在此奉上封装好的dm_pb2.py文件点击下载,大家放在自己的脚本同级目录下即可。最后祝大家玩得开心能给点个赞么?
在这里插入图片描述

六.参考

b站弹幕 Protobuf 格式解析

Python实现对Bilibili视频点赞等信息的爬取

b站弹幕 so文件解析/逆序列化

python进行B站av号和bv号的转换

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/995783.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

NFS文件共享系统(K8S)

概述 部署NFS文件共享服务&#xff0c;为Kubernetes提供NFS共享做准备 步骤 安装软件 yum -y install nfs-utils 配置NFS(exports) 编辑 /etc/exports 文件。每一行代表一个共享目录&#xff0c;描述目录如何共享 编写规则&#xff1a; # <共享目录> [客户端1 选项…

Spring修炼之路--基础知识

一、核心概念 1.1软件模块化 软件模块化是一种软件开发的设计模式&#xff0c;它将一个大型的软件系统划分成多个独立的模块&#xff0c;每个模块都有自己的功能和接口&#xff0c;并且能够与其他模块独立地工作1. 软件模块化设计可以使软件不至于随着逐渐变大而变得不可控&am…

​ICCV 2023 | 图像分割全新思路:仅用文本描述实现图像分割!

论文链接&#xff1a; https://arxiv.org/pdf/2308.14575.pdf 代码链接&#xff1a; https://github.com/fawnliu/TRIS 基本概念&#xff1a;Referring Image Segmentation&#xff08;RIS&#xff09;是一种图像分割技术&#xff0c;旨在根据自然语言表达来标记图像或视频中表…

教师节 | 拓世AI这样用,教案不再费神,辅助教师教学全流程

随着科技的不断进步&#xff0c;人工智能和大数据技术所带来的新的信息技术革命在每个细分领域生根发芽&#xff0c;教育领域也不例外。这个新时代的教育充满了挑战和机遇&#xff0c;科技的发展正引领着教育走向一个全新的境界。 教育是社会进步的重要引擎&#xff0c;教师是…

Ubuntu23.10将推出全磁盘加密功能,提高系统安全性

Canonical 宣布其即将推出的 Ubuntu 23.10&#xff08;Mantic Minotaur&#xff09;将引入基于 TPM 的全磁盘加密的初步支持。这个特性将利用系统可信平台模块&#xff08;TPM&#xff09;&#xff0c;在系统级别上进行全磁盘加密&#xff0c;从而提高系统的安全性。 但需要注…

【zip密码】7z分卷压缩如何加密?

想要压缩的文件过大&#xff0c;想要在压缩过程中将文件拆分为几个压缩包并且同时为所有压缩包设置加密应该如何设置&#xff1f; 想要分卷压缩文件并加密一起操作就可以完成了&#xff0c;设置方法如下&#xff1a; 打开7-zip&#xff0c;选中需要压缩的文件&#xff0c;选择…

大数据技术之Hadoop:提交MapReduce任务到YARN执行(八)

目录 一、前言 二、示例程序 2.1 提交wordcount示例程序 2.2 提交求圆周率示例程序 三、写在最后 一、前言 我们前面提到了MapReduce&#xff0c;也说了现在几乎没有人再写MapReduce代码了&#xff0c;因为它已经过时了。然而不写代码不意味着它没用&#xff0c;当下很火…

两性养生网站源码 生活类减肥网站源码 健康网模板源码 支持QQ登录和百度主动推送

本套模板非常适合生活类&#xff0c;两性类&#xff0c;减肥类等等类型的网站&#xff0c;这类型网站比较好做流量&#xff0c;因为客户群体众多&#xff0c; 可以自行改内容为其他类型网站模板总体非常简洁漂亮&#xff0c;配色合理&#xff0c;视觉舒服&#xff0c;并且配合…

合创汽车V09纵享商务丝滑?预售价32万元起,正式宣布大规模生产

合创汽车正式宣布&#xff0c;旗下新款车型V09已于9月10日开始大规模生产&#xff0c;并预计将于10月13日正式上市。V09作为中大型纯电动MPV的代表之一&#xff0c;备受瞩目。该车型是广汽新能源和蔚来汽车共同成立的广汽蔚来改为广汽集团和珠江投管共同投资的高端品牌——合创…

C语言练习:输入日期输出该日期为当年第几天

用scanf()输入某年某月某日&#xff0c;判断这一天是这一年的第几天。以3月5日为例&#xff0c;应该先把前两个月的加起来&#xff0c;然后再加上5天即本年的第几天&#xff0c;特殊情况&#xff0c;闰年且输入月份≥3时需考虑多加一天。注&#xff1a;判断年份是否为闰年的方法…

Web server failed to start. Port 8080 was already in use.之解决方法

问题&#xff1a; Web server failed to start. Port 8080 was already in use&#xff0c;这句错误描述意思是当前程序的端口号8080被占用了&#xff0c;需要将占用该端口的程序停止掉才行&#xff1b;错误如图所示&#xff1a; 解决方法&#xff1a; 按住winr&#xff0c;输入…

AI在医疗保健领域:突破界限,救治生命

文章目录 AI在医学影像分析中的应用AI在疾病预测和早期诊断中的作用个性化治疗和药物研发医疗数据管理和隐私保护未来展望 &#x1f389;欢迎来到AIGC人工智能专栏~AI在医疗保健领域&#xff1a;突破界限&#xff0c;救治生命 ☆* o(≧▽≦)o *☆嗨~我是IT陈寒&#x1f379;✨博…

第17章_瑞萨MCU零基础入门系列教程之CAN FD 模块

本教程基于韦东山百问网出的 DShanMCU-RA6M5开发板 进行编写&#xff0c;需要的同学可以在这里获取&#xff1a; https://item.taobao.com/item.htm?id728461040949 配套资料获取&#xff1a;https://renesas-docs.100ask.net 瑞萨MCU零基础入门系列教程汇总&#xff1a; ht…

buuctf crypto 【Dangerous RSA】解题记录

1.打开文件 2.看到e非常小&#xff0c;c和n都很大&#xff0c;应该是低加密指数&#xff0c;上脚本 from gmpy2 import * from Crypto.Util.number import * n0x52d483c27cd806550fbe0e37a61af2e7cf5e0efb723dfc81174c918a27627779b21fa3c851e9e94188eaee3d5cd6f752406a43fbec…

王道考研:作业调度、内存调度、进程调度;进程的挂起状态;进程调度的时机、闲逛进程;调度算法的评价指标;不同调度算法性能的对比分析

一、作业调度、内存调度、进程调度 有时候使用手机切换进程的时候会出现卡顿的现象&#xff0c;这就是因为中级调度的原语 二、进程调度的时机 普通的临界区就是临界资源&#xff0c;比如访问打印机 调度程序是操作系统内核的一个模块 三、调度算法的评价指标 四、不同的调度…

栅格转换为CSV数据时如何优化数据文件的大小

在一些模型运算过程中我们需要将栅格数据转换为CSV数据进行计算输入。但栅格数据转换成矢量&#xff08;CSV&#xff09;后非常非常大。这个数据通常会是GB级别的。对于我们一般电脑运算的话&#xff0c;可能会非常困难&#xff0c;而且运算越复杂你不成功的几率越大 &#xf…

RESP无法连接linux上redis问题

1.本机无法ping通虚拟机IP 没有打开服务&#xff08;这只是无法ping通虚拟机的一种原因&#xff09; 其他原因可以参考 虚拟机ping不通的几种原因及解决办法_虚拟机ping不通主机_在键盘上弹钢琴的菜菜的博客-CSDN博客 2.未关闭linux系统的防火墙导致无法连接redis 查看防火墙…

最新清理删除Mac电脑内存空间方法教程

Mac电脑使用的时间越久&#xff0c;系统的运行就会变的越卡顿&#xff0c;这是Mac os会出现的正常现象&#xff0c;卡顿的原因主要是系统缓存文件占用了较多的磁盘空间&#xff0c;或者Mac的内存空间已满。如果你的Mac运行速度变慢&#xff0c;很有可能是因为磁盘内存被过度占用…

【PHY】3GPP UE能力类别的变化

博主未授权任何人或组织机构转载博主任何原创文章&#xff0c;感谢各位对原创的支持&#xff01; 博主链接 本人就职于国际知名终端厂商&#xff0c;负责modem芯片研发。 在5G早期负责终端数据业务层、核心网相关的开发工作&#xff0c;目前牵头6G算力网络技术标准研究。 博客…

态、势、感、知与时空、关系

态势感知是一种通过收集、整合、分析和解释大量的时空数据&#xff0c;以获取关于特定领域、地区或事件的全面理解的过程。时空和关系在态势感知中扮演着非常重要的角色。 态&#xff1a;态指的是物体或系统所处的状态或状况。在不同的态下&#xff0c;物体或系统的性质、行为和…