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脚本实现代码行数统计代码分享
Mar 10 Python
Python爬虫框架Scrapy实战之批量抓取招聘信息
Aug 07 Python
python 时间戳与格式化时间的转化实现代码
Mar 23 Python
PyCharm 创建指定版本的 Django(超详图解教程)
Jun 18 Python
Django后台管理系统的图文使用教学
Jan 20 Python
Python列表倒序输出及其效率详解
Mar 04 Python
Python第三方包之DingDingBot钉钉机器人
Apr 09 Python
python实现交并比IOU教程
Apr 16 Python
基于python实现地址和经纬度转换
May 19 Python
python实现密码验证合格程序的思路详解
Jun 01 Python
浅谈keras中的keras.utils.to_categorical用法
Jul 02 Python
python 基于opencv实现图像增强
Dec 23 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排序之二维数组的按照字母排序实现代码
2011/08/13 PHP
PHP使用mysqldump命令导出数据库
2015/04/14 PHP
对比PHP对MySQL的缓冲查询和无缓冲查询
2016/07/01 PHP
简单实现PHP留言板功能
2016/12/21 PHP
php文件上传类的分享
2017/07/06 PHP
Laravel学习教程之model validation的使用示例
2017/10/23 PHP
解决在laravel中auth建立时候遇到的问题
2019/10/15 PHP
php 自定义函数实现将数据 以excel 表格形式导出示例
2019/11/13 PHP
Gambit vs CL BO3 第二场 2.13
2021/03/10 DOTA
更优雅的事件触发兼容
2011/10/24 Javascript
JS获取select的value和text值的简单实例
2014/02/26 Javascript
JavaScript函数详解
2014/11/17 Javascript
浅析AngularJS Filter用法
2015/12/28 Javascript
详解JavaScript表单验证(E-mail 验证)
2016/03/31 Javascript
jquery获取file表单选择文件的路径、名字、大小、类型
2019/01/18 jQuery
JS实现的类似微信聊天效果示例
2019/01/29 Javascript
亲自动手实现vue日历控件
2019/06/26 Javascript
ElementUI之Message功能拓展详解
2019/10/18 Javascript
[01:18:35]DOTA2-DPC中国联赛 正赛 Elephant vs LBZS BO3 第一场 1月29日
2021/03/11 DOTA
Python中用memcached来减少数据库查询次数的教程
2015/04/07 Python
python虚拟环境virualenv的安装与使用
2016/12/18 Python
Python内置模块logging用法实例分析
2018/02/12 Python
深入浅析Python的类
2018/06/22 Python
浅谈django三种缓存模式的使用及注意点
2018/09/30 Python
Python爬取数据保存为Json格式的代码示例
2019/04/09 Python
英国品牌男装折扣网站:Brown Bag
2018/03/08 全球购物
香港最新科技与优质家居产品购物网站:J SELECT
2018/08/21 全球购物
牦牛毛户外探险服装:Kora
2019/02/08 全球购物
定制别致的瑜伽垫:Sugarmat
2019/06/21 全球购物
软件测试英文面试题
2012/10/14 面试题
客服端调用EJB对象的几个基本步骤
2012/01/15 面试题
类的返射机制中的包及核心类
2016/09/12 面试题
法定代表人身份证明书
2014/09/10 职场文书
党的群众路线教育实践活动总结材料
2014/10/30 职场文书
幼儿园教师培训心得体会
2016/01/21 职场文书
python opencv旋转图片的使用方法
2021/06/04 Python