Python基于Tkinter开发一个爬取B站直播弹幕的工具


Posted in Python onMay 06, 2021

简介

使用Python Tkinter开发一个爬取B站直播弹幕的工具,启动后在弹窗中输入房间号即可,弹幕内容会保存在脚本文件同级目录下的.log扩展名的文件中

开发工具

  • python 3.7.9
  • pycharm 2019.3.5

实现代码

import threading
import time
import tkinter.simpledialog  # 使用Tkinter前需要先导入
from tkinter import END, messagebox

import requests

# 全局变量,用于标识线程是否退出
is_exit = True


# B站获取弹幕对象
class Danmu():
    def __init__(self, room_id):
        # 弹幕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': room_id,
            'csrf_token': '',
            'csrf': '',
            'visit_id': '',
        }
        # 日志写对象
        self.log_file_write = open('danmu.log', mode='a', encoding='utf-8')
        # 读取日志
        log_file_read = open('danmu.log', mode='r', encoding='utf-8')
        self.log = log_file_read.readlines()

    def get_danmu(self):
        # 暂停0.5防止cpu占用过高
        time.sleep(1)
        # 获取直播间弹幕
        html = requests.post(url=self.url, headers=self.headers, data=self.data).json()
        # 解析弹幕列表
        for content in html['data']['room']:
            # 获取昵称
            nickname = content['nickname']
            # 获取发言
            text = content['text']
            # 获取发言时间
            timeline = content['timeline']
            # 记录发言
            msg = timeline + ' ' + nickname + ': ' + text
            # 判断对应消息是否存在于日志,如果和最后一条相同则打印并保存
            if msg + '\n' not in self.log:
                # 打印消息
                listb.insert(END, msg)
                listb.see(END)
                # 保存日志
                self.log_file_write.write(msg + '\n')
                # 添加到日志列表
                self.log.append(msg + '\n')
            # 清空变量缓存
            nickname = ''
            text = ''
            timeline = ''
            msg = ''


# 线程对象
def bilibili(room_id):
    # 创建bDanmu实例
    bDanmu = Danmu(room_id)
    # 获取弹幕
    bDanmu.get_danmu()


class BilibiliThread(threading.Thread):
    def __init__(self, room_id=None):
        threading.Thread.__init__(self)
        self.room_id = room_id

    # 重写run()方法
    def run(self):
        global is_exit
        while not is_exit:
            print(self.room_id)
            bilibili(self.room_id)
            # 暂停防止cpu占用过高
            time.sleep(0.5)


def author():
    # 弹出对话框
    messagebox.showinfo(title='关于', message='作者:阿壮Jonson\n日期:2021年2月4日\n微信公众号:科技猫')


# 实例化object,建立窗口window
window = tkinter.Tk()
# 给窗口的可视化起名字
window.title('BiliBli弹幕查看工具')
# 设定窗口的大小(长 * 宽)
window.minsize(300, 500)
window.geometry('400x600+250+100')

# 菜单栏
menubar = tkinter.Menu(window)
# Open放在菜单栏中,就是装入容器
menubar.add_command(label='关于', command=author)
# 创建菜单栏完成后,配置让菜单栏menubar显示出来
window.config(menu=menubar)

# 创建一个主frame,长在主window窗口上
frame = tkinter.Frame(window)
frame.pack()

# 创建第二层框架frame,长在主框架frame上面
# 上
frame_t = tkinter.Frame(frame)
# 下
frame_b = tkinter.Frame(frame)
frame_t.pack(side=tkinter.TOP)
frame_b.pack(side=tkinter.BOTTOM)

# 创建标签
tkinter.Label(frame_t, text='请输入房间号:', width=10, font=('Arial', 10)).pack(side=tkinter.LEFT)
# 显示成明文形式
default_text = tkinter.StringVar()
default_text.set("21089733")
e1 = tkinter.Entry(frame_t, show=None, width=15, textvariable=default_text, font=('Arial', 10))
e1.pack(side=tkinter.LEFT)


# 定义两个触发事件时的函数start_point和end_point(注意:因为Python的执行顺序是从上往下,所以函数一定要放在按钮的上面)
# 开始
def start_point():
    try:
        room = e1.get()
        room_int = int(room)
        e1.configure(state=tkinter.DISABLED)
        b1.configure(state=tkinter.DISABLED)
        b2.configure(state=tkinter.NORMAL)
        if room_int is not None:
            global is_exit
            is_exit = False
            t = BilibiliThread()
            t.room_id = room_int
            # 创建获取弹幕线程
            t.setDaemon(True)
            t.start()
    except ValueError:
        messagebox.showinfo(title='警告', message='输入的房间号格式不正确,请再次尝试输入!')


# 停止
def end_point():
    global is_exit
    is_exit = True
    e1.configure(state=tkinter.NORMAL)
    b1.configure(state=tkinter.NORMAL)
    b2.configure(state=tkinter.DISABLED)


# 创建并放置两个按钮分别触发两种情况
b1 = tkinter.Button(frame_t, text='开始', width=10, command=start_point, font=('Arial', 10))
b1.pack(side=tkinter.LEFT)
b2 = tkinter.Button(frame_t, text='停止', width=10, command=end_point, font=('Arial', 10))
b2.pack(side=tkinter.LEFT)

# 滚动条
sc = tkinter.Scrollbar(frame_b)
sc.pack(side=tkinter.RIGHT, fill=tkinter.Y)
# Listbox控件
listb = tkinter.Listbox(frame_b, yscrollcommand=sc.set, width=200, height=120)
# 将部件放置到主窗口中
listb.pack(side=tkinter.LEFT, fill=tkinter.BOTH, expand=True)
# 滚动条动,列表跟着动
sc.config(command=listb.yview)

# 主窗口循环显示
window.mainloop()

爬取效果

Python基于Tkinter开发一个爬取B站直播弹幕的工具

Github地址:

https://github.com/jonssonyan/bilibli-danmu

以上就是Python Tkinter开发一个爬取B站直播弹幕的工具的详细内容,更多关于Python 爬取B站直播弹幕的资料请关注三水点靠木其它相关文章!

Python 相关文章推荐
Python实现把xml或xsl转换为html格式
Apr 08 Python
python中类变量与成员变量的使用注意点总结
Apr 29 Python
Python中常用信号signal类型实例
Jan 25 Python
Python实现查看系统启动项功能示例
May 10 Python
Django中的Model操作表的实现
Jul 24 Python
python如何生成各种随机分布图
Aug 27 Python
在python中获取div的文本内容并和想定结果进行对比详解
Jan 02 Python
解决win7操作系统Python3.7.1安装后启动提示缺少.dll文件问题
Jul 15 Python
Python封装成可带参数的EXE安装包实例
Aug 24 Python
Django框架序列化与反序列化操作详解
Nov 01 Python
Spring @Enable模块驱动原理及使用实例
Jun 23 Python
Python实现Canny及Hough算法代码实例解析
Aug 06 Python
Python爬虫之爬取最新更新的小说网站
May 06 #Python
Python基础之操作MySQL数据库
Python 如何安装Selenium
Django实现在线无水印抖音视频下载(附源码及地址)
Django给表单添加honeypot验证增加安全性
Django利用AJAX技术实现博文实时搜索
May 06 #Python
python 如何获取页面所有a标签下href的值
May 06 #Python
You might like
Oracle 常见问题解答
2006/10/09 PHP
PHP中通过fopen()函数访问远程文件示例
2014/11/18 PHP
基于PHP实现通过照片获取ip地址
2016/04/26 PHP
PHP实时统计中文字数和区别
2019/02/28 PHP
Laravel框架自定义分页样式操作示例
2020/01/26 PHP
jquery text,radio,checkbox,select操作实现代码
2009/07/09 Javascript
Javascript 学习笔记 错误处理
2009/07/30 Javascript
查看大图功能代码jquery版
2013/11/05 Javascript
PHP实现的各种中文编码转换类分享
2015/01/23 Javascript
jQuery实现复选框批量选择与反选的方法
2015/06/17 Javascript
浅谈jQuery 中的事件冒泡和阻止默认行为
2016/05/28 Javascript
利用jquery给指定的table动态添加一行、删除一行的方法
2016/10/12 Javascript
Vue.js 60分钟快速入门教程
2017/03/28 Javascript
JavaScript实现前端实时搜索功能
2020/03/26 Javascript
HTML5实现微信拍摄上传照片功能
2017/04/21 Javascript
浅谈jQuery框架Ajax常用选项
2017/07/08 jQuery
nodejs 生成和导出 word的实例代码
2018/07/31 NodeJs
详解Vue组件插槽的使用以及调用组件内的方法
2018/11/13 Javascript
基于JavaScript伪随机正态分布代码实例
2019/11/07 Javascript
小程序实现按下录音松开识别语音
2019/11/22 Javascript
vue-cli3单页构建大型项目方案
2020/04/07 Javascript
[51:53]DOTA2-DPC中国联赛 正赛 RNG vs Dragon BO3 第二场 1月24日
2021/03/11 DOTA
一篇文章入门Python生态系统(Python新手入门指导)
2015/12/11 Python
python模拟登录并且保持cookie的方法详解
2017/04/04 Python
python梯度下降法的简单示例
2018/08/31 Python
Python实现的各种常见分布算法示例
2018/12/13 Python
对python_discover方法遍历所有执行的用例详解
2019/02/13 Python
OpenCV 边缘检测
2019/07/10 Python
读书月活动方案
2014/05/22 职场文书
销售类求职信
2014/06/13 职场文书
金融专业求职信
2014/08/05 职场文书
房屋产权共有协议书范本
2014/11/03 职场文书
2014年安全员工作总结
2014/11/13 职场文书
应届生简历自我评价
2015/03/11 职场文书
Vue组件更新数据v-model不生效的解决
2022/04/02 Vue.js
Python数组变形的几种实现方法
2022/05/30 Python