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实现strcmp函数功能示例
Mar 25 Python
Python中的Numpy入门教程
Apr 26 Python
python字符串的常用操作方法小结
May 21 Python
python实现中文转换url编码的方法
Jun 14 Python
python安装教程
Feb 28 Python
Python生成短uuid的方法实例详解
May 29 Python
python itchat实现调用微信接口的第三方模块方法
Jun 11 Python
django 2.2和mysql使用的常见问题
Jul 18 Python
python3将变量写入SQL语句的实现方式
Mar 02 Python
Python之多进程与多线程的使用
Feb 23 Python
Python基础之操作MySQL数据库
May 06 Python
python识别围棋定位棋盘位置
Jul 26 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
用libTemplate实现静态网页的生成
2006/10/09 PHP
PHP守护进程化在C和PHP环境下的实现
2017/11/21 PHP
浅谈PHPANALYSIS提取关键字
2019/03/08 PHP
php判断某个方法是否存在函数function_exists (),method_exists()与is_callable()区别与用法解析
2020/04/20 PHP
Laravel框架源码解析之反射的使用详解
2020/05/14 PHP
javascript提取URL的搜索字符串中的参数(自定义函数实现)
2013/01/22 Javascript
鼠标移到图片上变大显示而不是放大镜效果
2014/06/15 Javascript
JS非Alert实现网页右下角“未读信息”效果弹窗
2015/09/26 Javascript
JavaScript中自带的 reduce()方法使用示例详解
2016/08/10 Javascript
微信小程序movable view移动图片和双指缩放实例代码
2017/08/08 Javascript
JS正则表达式完美实现身份证校验功能
2017/10/18 Javascript
JavaScript中ES6规范中let和const的用法和区别
2020/08/06 Javascript
Python ldap实现登录实例代码
2016/09/30 Python
Python实现随机生成有效手机号码及身份证功能示例
2017/06/05 Python
python脚本监控Tomcat服务器的方法
2018/07/06 Python
python 解决动态的定义变量名,并给其赋值的方法(大数据处理)
2018/11/10 Python
Python之时间和日期使用小结
2019/02/14 Python
Python3 翻转二叉树的实现
2019/09/30 Python
python数值基础知识浅析
2019/11/19 Python
python实现字典嵌套列表取值
2019/12/16 Python
python如何通过twisted搭建socket服务
2020/02/03 Python
如何基于Python实现数字类型转换
2020/02/07 Python
python脚本和网页有何区别
2020/07/02 Python
详解CSS3媒体查询响应式布局bootstrap 框架原理实战(推荐)
2020/11/16 HTML / CSS
施华洛世奇德国官网:SWAROVSKI德国
2017/02/01 全球购物
Footshop罗马尼亚:最好的运动鞋选择
2019/09/10 全球购物
室内设计专业个人的自我评价
2013/10/19 职场文书
财务部出纳岗位职责
2013/12/22 职场文书
演讲比赛的活动方案
2014/08/28 职场文书
医院党员公开承诺书
2014/08/30 职场文书
试用期转正员工自我评价
2014/09/18 职场文书
2014年教育教学工作总结
2014/11/13 职场文书
卫生院义诊活动总结
2015/05/07 职场文书
开发一个封装iframe的vue组件
2021/03/29 Vue.js
如何用PHP实现多线程编程
2021/05/26 PHP
python b站视频下载的五种版本
2021/05/27 Python