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中迭代器(iterator)用法实例分析
Apr 29 Python
Python中使用装饰器时需要注意的一些问题
May 11 Python
python实现查找excel里某一列重复数据并且剔除后打印的方法
May 26 Python
python数据预处理之将类别数据转换为数值的方法
Jul 05 Python
使用 Python 实现文件递归遍历的三种方式
Jul 18 Python
python全栈要学什么 python全栈学习路线
Jun 28 Python
使用python turtle画高达
Jan 19 Python
详解python logging日志传输
Jul 01 Python
在 Python 中使用 MQTT的方法
Aug 18 Python
如何使用pycharm连接Databricks的步骤详解
Sep 23 Python
mac系统下安装pycharm、永久激活、中文汉化详细教程
Nov 24 Python
python读取excel数据并且画图的实现示例
Feb 08 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
浅析PHP原理之变量(Variables inside PHP)
2013/08/09 PHP
Windows下安装PHP单元测试环境PHPUnit图文教程
2014/10/24 PHP
PHP也能干大事之PHP中的编码解码详解
2015/04/20 PHP
PHP Post获取不到非表单数据的问题解决办法
2018/02/27 PHP
javascript 简单高效判断数据类型 系列函数 By shawl.qiu
2007/03/06 Javascript
jQuery UI Datepicker length为空或不是对象错误的解决方法
2010/12/19 Javascript
js控制CSS样式属性语法对照表
2012/12/11 Javascript
基于jquery插件制作左右按钮与标题文字图片切换效果
2013/11/07 Javascript
jQuery .tmpl() 用法示例介绍
2014/08/21 Javascript
使用jQuery.wechat构建微信WEB应用
2014/10/09 Javascript
鼠标经过子元素触发mouseout,mouseover事件的解决方案
2015/07/26 Javascript
jQuery动画效果实现图片无缝连续滚动
2016/01/12 Javascript
Bootstrap学习笔记之css样式设计(1)
2016/06/07 Javascript
JavaScript数组去重的几种方法效率测试
2016/10/23 Javascript
浅谈ECMAScript6新特性之let、const
2017/08/02 Javascript
vue组件编写之todolist组件实例详解
2018/01/22 Javascript
vue项目中,main.js,App.vue,index.html的调用方法
2018/09/20 Javascript
在Bootstrap开发框架中使用dataTable直接录入表格行数据的方法
2018/10/25 Javascript
layui固定下拉框的显示条数(有滚动条)的方法
2019/09/10 Javascript
vue 实现input表单元素的disabled示例
2019/10/28 Javascript
JS实现网页时钟特效
2020/03/25 Javascript
jQuery 动画与停止动画效果实例详解
2020/05/19 jQuery
[01:14]DOTA2亚洲邀请赛小组赛赛前花絮
2017/03/27 DOTA
Python中的random()方法的使用介绍
2015/05/15 Python
一步步教你用Python实现2048小游戏
2017/01/19 Python
利用python实现命令行有道词典的方法示例
2017/01/31 Python
Python3如何解决字符编码问题详解
2017/04/23 Python
python 表达式和语句及for、while循环练习实例
2017/07/07 Python
python 绘制拟合曲线并加指定点标识的实现
2019/07/10 Python
python多线程semaphore实现线程数控制的示例
2020/08/10 Python
python中entry用法讲解
2020/12/04 Python
颇特女士香港官网:NET-A-PORTER香港
2021/03/08 全球购物
汽车专业毕业生自荐信
2013/11/03 职场文书
生产工厂门卫岗位职责
2014/09/26 职场文书
个人委托书范本汇总
2014/10/01 职场文书
负责培养人意见
2015/06/05 职场文书