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实现ping的方法
Jul 06 Python
用Python写一个无界面的2048小游戏
May 24 Python
python模块之time模块(实例讲解)
Sep 13 Python
Python编程实现蚁群算法详解
Nov 13 Python
Mac下Anaconda的安装和使用教程
Nov 29 Python
Python Django框架实现应用添加logging日志操作示例
May 17 Python
使用Python3内置文档高效学习以及官方中文文档
May 19 Python
Python算法的时间复杂度和空间复杂度(实例解析)
Nov 19 Python
python实现局域网内实时通信代码
Dec 22 Python
Python使用py2neo操作图数据库neo4j的方法详解
Jan 13 Python
完美解决ARIMA模型中plot_acf画不出图的问题
Jun 04 Python
python Autopep8实现按PEP8风格自动排版Python代码
Mar 02 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
咖啡磨器 如何选购一台适合家用的意式磨豆机
2021/03/05 新手入门
PHP调用三种数据库的方法(1)
2006/10/09 PHP
详解PHP中array_rand函数的使用方法
2016/09/11 PHP
Yii2中简单的场景使用介绍
2017/06/02 PHP
浅析PHP数据导出知识点
2018/02/17 PHP
JS创建优美的页面滑动块效果 - Glider.js
2007/09/27 Javascript
JavaScript 函数参数是传值(byVal)还是传址(byRef) 分享
2013/07/02 Javascript
JS命名空间的另一种实现
2013/08/09 Javascript
js中创建对象的几种方式示例介绍
2014/01/26 Javascript
javascript学习笔记之10个原生技巧
2014/05/21 Javascript
Javascript的表单验证-揭开正则表达式的面纱
2016/03/18 Javascript
老生常谈JavaScript 正则表达式语法
2016/08/20 Javascript
手机图片预览插件photoswipe.js使用总结
2016/08/25 Javascript
详解JavaScript作用域和作用域链
2019/03/19 Javascript
vue操作dom元素的3种方法示例
2020/09/20 Javascript
[00:35]DOTA2上海特级锦标赛 Newbee战队宣传片
2016/03/03 DOTA
实例解析Python设计模式编程之桥接模式的运用
2016/03/02 Python
Ubuntu+python将nii图像保存成png格式
2019/07/18 Python
python 模拟创建seafile 目录操作示例
2019/09/26 Python
Django中使用haystack+whoosh实现搜索功能
2019/10/08 Python
Python 、Pycharm、Anaconda三者的区别与联系、安装过程及注意事项
2019/10/11 Python
pygame实现俄罗斯方块游戏(基础篇3)
2019/10/29 Python
Python3和pyqt5实现控件数据动态显示方式
2019/12/13 Python
基于spring boot 日志(logback)报错的解决方式
2020/02/20 Python
Python新手如何理解循环加载模块
2020/05/29 Python
Python的Tqdm模块实现进度条配置
2021/02/24 Python
英国Office鞋店德国网站:在线购买鞋子、靴子和运动鞋
2018/12/19 全球购物
法国在线药房:DoctiPharma
2020/10/21 全球购物
国际贸易专业推荐信
2013/11/15 职场文书
自我鉴定注意事项
2014/01/19 职场文书
爱护花草树木的标语
2014/06/11 职场文书
先进班组材料范文
2014/12/25 职场文书
党支部考察意见范文
2015/06/02 职场文书
2016年秋季趣味运动会开幕词
2016/03/04 职场文书
JavaScript执行机制详细介绍
2021/12/06 Javascript
Oracle数据库中通用的函数实例详解
2022/03/25 Oracle