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 3.6.4 安装配置方法图文教程
Sep 18 Python
对python opencv 添加文字 cv2.putText 的各参数介绍
Dec 05 Python
python实现对任意大小图片均匀切割的示例
Dec 05 Python
Python使用pyshp库读取shapefile信息的方法
Dec 29 Python
Python多进程入门、分布式进程数据共享实例详解
Jun 03 Python
django 控制页面跳转的例子
Aug 06 Python
python fuzzywuzzy模块模糊字符串匹配详细用法
Aug 29 Python
Python 取numpy数组的某几行某几列方法
Oct 24 Python
利用matplotlib实现根据实时数据动态更新图形
Dec 13 Python
python base64库给用户名或密码加密的流程
Jan 02 Python
python 图像增强算法实现详解
Jan 24 Python
python opencv通过4坐标剪裁图片
Jun 05 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获取金书网的书名的实现代码
2010/06/11 PHP
tp5.0框架隐藏index.php入口文件及模块和控制器的方法分析
2020/02/11 PHP
33个优秀的 jQuery 图片展示插件分享
2012/03/14 Javascript
特殊情况下如何获取span里面的值
2014/05/20 Javascript
jquery动态加载js/css文件方法(自写小函数)
2014/10/11 Javascript
深入理解JavaScript系列(22):S.O.L.I.D五大原则之依赖倒置原则DIP详解
2015/03/05 Javascript
Vue.js系列之项目搭建(1)
2017/01/03 Javascript
JS实现DIV高度自适应窗口示例
2017/02/16 Javascript
javascript将非数值转换为数值
2018/09/13 Javascript
js实现下拉框二级联动
2018/12/04 Javascript
微信小程序登录session的使用
2019/03/17 Javascript
js实现鼠标点击页面弹出自定义文字效果
2019/12/24 Javascript
python实现决策树、随机森林的简单原理
2018/03/26 Python
python中map的基本用法示例
2018/09/10 Python
Python图像处理之直线和曲线的拟合与绘制【curve_fit()应用】
2018/12/26 Python
Python实现合并excel表格的方法分析
2019/04/13 Python
Python3.5面向对象与继承图文实例详解
2019/04/24 Python
详解用python实现基本的学生管理系统(文件存储版)(python3)
2019/04/25 Python
Python配置虚拟环境图文步骤
2019/05/20 Python
python使用Matplotlib改变坐标轴的默认位置
2019/10/18 Python
基于python实现文件加密功能
2020/01/06 Python
python正则表达式实例代码
2020/03/03 Python
Python语言编写智力问答小游戏功能
2020/10/13 Python
香港太阳眼镜网上商店:SmartBuyGlasses香港
2016/07/22 全球购物
售后服务经理岗位职责范本
2014/02/22 职场文书
财务总监管理岗位职责
2014/03/08 职场文书
工业设计毕业生自荐信
2014/04/13 职场文书
《陈毅探母》教学反思
2014/05/01 职场文书
党的群众路线教育实践活动个人对照检查材料(教师)
2014/11/04 职场文书
中英文求职信范文
2015/03/19 职场文书
2015年银行客户经理工作总结
2015/04/01 职场文书
学术研讨会主持词
2015/07/04 职场文书
Python Pandas知识点之缺失值处理详解
2021/05/11 Python
分析并发编程之LongAdder原理
2021/06/29 Java/Android
JavaScript高级程序设计之基本引用类型
2021/11/17 Javascript
MySQL池化框架学习接池自定义
2022/07/23 MySQL