适用于linux的bilibiliB站直播间弹幕爬虫脚本

适用于linux的bilibiliB站直播间弹幕爬虫脚本,命令行运行之,输入到命令行,部分内容参考自网络,代码底部可见原始代码出处
BUFF:然而,经测试,每次爬只能读取10条弹幕记录,这就使得在(sleeptime*10)(每秒)<弹幕新增量(每秒)时出现弹幕丢失的情况,此时需要调短sleeptime,由于本脚本是自用目的(我的粉丝数是个数),因此该bug对我本人暂无影响,有需要修复该bug的读者请留言或自行修复

python 复制代码
# -*- coding:utf-8 -*-
# 时间:2024/4/26
# 原作者:猫先生的早茶
# 二创:wc1945451904@163.com
#!/usr/bin/python
#"""
#    获取bilibili直播间弹幕
#    房间号从网页源代码中获取
#    打开直播画面后,按ctrl+u 打开网页源代码,按ctrl+f 搜索 room_id
#    搜到的"room_id":1016中,1016就是房间号 
#    获取不同房间的弹幕:修改代码第26行的roomid的值为对应的房间号roomid,或者通过公共设置处的变量来设置之
#    先在直播间手动输入一条弹幕,再开启该脚本
#"""

# wc:使用python在命令行中启动脚本,需要提前安装request 包,conda install requests或者
# pip install requests

import requests;
import time;
#公共设置
sleeptime = 3;#此处修改抓取间隔
groomid = '12159402'#二创者的直播间id(^_^)
if(groomid==''):
    print("未设置目标直播间id");
    return;
#彩色转译
RED = '\033[91m'
GREEN = '\033[92m'
YELLOW = '\033[93m'
BLUE = '\033[94m'
MAGENTA = '\033[95m'
CYAN = '\033[96m'
RESET = '\033[0m'
class Danmu():
    def __init__(self):
        self.t = False;#保证第一次循环一定要获取弹幕,然后进入第二循环
        self.lastMsg = '';
        self.lastTime = '';
        self.lastNickname = '';

        # 弹幕url
        self.url = 'https://api.live.bilibili.com/xlive/web-room/v1/dM/gethistory';
        # 请求头
        self.headers = {
            'Host':'api.live.bilibili.com',
            'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:78.0) Gecko/20100101 Firefox/78.0',
        }
        # 定义POST传递的参数
        self.data = {
            'roomid':groomid,#!!!修改为roomId
            'csrf_token':'',
            'csrf':'',
            'visit_id':'',
        }
        
    def get_danmu_once(self):
        # 第一次获取直播间弹幕,全部打印
        html = requests.post(url=self.url,headers=self.headers,data=self.data).json();
        # 
        # 弹幕列表逐项提取
        #逻辑:先打印,再判断并修改self.t
        #如果弹幕很少,则会
        if self.t==False:
            for content in html['data']['room']:
                self.lastTime = content['timeline']
                self.lastNickname = content['nickname'];
                self.lastText = content['text'];
                print(f"{GREEN}{self.lastTime}{BLUE}{self.lastNickname}{RESET}"+'\t:'+self.lastText)
                #print('\t:'+self.lastText)
                #outmsg = self.lastTime+self.lastNickname+'\t:'+self.lastText;
                #print(outmsg);        
            if(self.lastTime!=''):
                self.t = True;
    
    def get_danmu_circle(self):
        # 后续获取直播间弹幕,则不可靠地找到上次记录的最后一条弹幕,然后输出其(不含)后面的弹幕
        html = requests.post(url=self.url,headers=self.headers,data=self.data).json();
        count = 0;#开关
        # 弹幕列表逐项提取
        for content in html['data']['room']:
            # 整合[     昵称+对话内容    ]输出
            if(count == 1):#此处为第一条新增弹幕,输出之
                self.lastTime = content['timeline']
                self.lastNickname = content['nickname'];
                self.lastText = content['text'];
                print(f"{GREEN}{self.lastTime}{BLUE}{self.lastNickname}{RESET}"+'\t:'+self.lastText)
                #outmsg = self.lastTime+self.lastNickname+'\t:'+self.lastText;
                #print(outmsg);
                
            # 判断新弹幕
            elif(self.lastTime>=content['timeline']
                 and self.lastNickname==content['nickname']
                 and self.lastText==content['text']):
                        count = 1;#
                        continue;
        #     sum+=1;
        # print("==============sum == %d",sum);


# 创建bDanmu实例
bDanmu = Danmu();

while bDanmu.t==False:#False表示爬虫的弹幕列表为空
    time.sleep(sleeptime);
    bDanmu.get_danmu_once();

while True:
    # 每隔x秒就检查一下直播间弹幕
    time.sleep(sleeptime);
    # 获取弹幕
    bDanmu.get_danmu_circle();  
                  
#原作者原文链接:https://blog.csdn.net/qq_43017750/article/details/107771744