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发送邮件附件以定时备份MySQL的教程
Apr 25 Python
Python导出数据到Excel可读取的CSV文件的方法
May 12 Python
通过Python使用saltstack生成服务器资产清单
Mar 01 Python
人机交互程序 python实现人机对话
Nov 14 Python
python+pyqt5实现KFC点餐收银系统
Jan 24 Python
用Python解数独的方法示例
Oct 24 Python
tensorflow 查看梯度方式
Feb 04 Python
使用Python3 poplib模块删除服务器多天前的邮件实现代码
Apr 24 Python
Python实现aes加密解密多种方法解析
May 15 Python
python操作redis数据库的三种方法
Sep 10 Python
用python写一个带有gui界面的密码生成器
Nov 06 Python
Python实现淘宝秒杀功能的示例代码
Jan 19 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中使用sleep函数实现定时任务实例分享
2014/08/21 PHP
php微信高级接口调用方法(自定义菜单接口、客服接口、二维码)
2016/11/28 PHP
PHP中include和require的区别实例分析
2017/05/07 PHP
thinkPHP中钩子的使用方法实例分析
2017/11/16 PHP
PHP框架实现WebSocket在线聊天通讯系统
2019/11/21 PHP
js设置控件的隐藏与显示的两种方法
2014/08/21 Javascript
JQuery表格拖动调整列宽效果(自己动手写的)
2014/09/01 Javascript
使用jQuery的easydrag插件实现可拖动的DIV弹出框
2016/02/19 Javascript
iscroll动态加载数据完美解决方法
2017/07/18 Javascript
使用vue点击li,获取当前点击li父辈元素的属性值方法
2018/09/12 Javascript
Vue中 key keep-alive的实现原理
2018/09/18 Javascript
JavaScript对象的特性与实践应用深入详解
2018/12/30 Javascript
快速解决layui弹窗按enter键不停弹窗的问题
2019/09/18 Javascript
javascript事件循环event loop的简单模型解释与应用分析
2020/03/14 Javascript
[01:05:30]VP vs TNC 2018国际邀请赛小组赛BO2 第一场 8.17
2018/08/20 DOTA
Python linecache.getline()读取文件中特定一行的脚本
2008/09/06 Python
实例解析Python的Twisted框架中Deferred对象的用法
2016/05/25 Python
python的dataframe和matrix的互换方法
2018/04/11 Python
实践Vim配置python开发环境
2018/07/02 Python
Python pygorithm模块用法示例【常见算法测试】
2018/08/16 Python
python 多个参数不为空校验方法
2019/02/14 Python
Python通过正则库爬取淘宝商品信息代码实例
2020/03/02 Python
iHerb中文官网:维生素、保健品和健康产品
2018/11/01 全球购物
巴西独家产品和现场演示购物网站:Shoptime
2019/07/11 全球购物
英国排名第一的餐具品牌:Denby Pottery
2019/11/01 全球购物
英语教学随笔感言
2014/02/20 职场文书
领导干部群众路线个人对照检查材料思想汇报
2014/09/30 职场文书
病危通知书样本
2015/04/17 职场文书
2015年乡镇工作总结范文
2015/04/22 职场文书
民事诉讼代理词
2015/05/25 职场文书
小学生读书笔记范文
2015/06/30 职场文书
患者身份识别制度
2015/08/06 职场文书
zabbix agent2 监控oracle数据库的方法
2021/05/13 Oracle
Python中的 Set 与 dict
2022/03/13 Python
vue配置型表格基于el-table拓展之table-plus组件
2022/04/12 Vue.js
Python matplotlib绘制条形统计图 处理多个实验多组观测值
2022/04/21 Python