Pyqt5 下载B站视频小软件

import os,re,time,datetime,sys,random,math,webbrowser,menub,threading,json
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5 import QtWidgets,QtGui,QtCore
from PyQt5.QtCore import * 
from Ui_video import Ui_MainWindow
from functools import partial
import requests
from bs4 import BeautifulSoup
from you_get import common as you_get  
#导入数据库
from PyQt5 import QtSql
from PyQt5.QtSql import QSqlQuery


class Mywindow(Ui_MainWindow,QMainWindow):
    progressChanged = QtCore.pyqtSignal(int)
    tips = QtCore.pyqtSignal(int)
    charudb = QtCore.pyqtSignal(int)
    def __init__(self):
        super().__init__()
        self.setupUi(self)
        self.tableWidget.setRowCount(10)
        self.current_page = 1
        self.action.triggered.connect(lambda:self.savedir()) # 设置保存路径点击
        self.action_2.triggered.connect(lambda:self.ask()) # 常见问题
        self.action_3.triggered.connect(lambda:self.contact()) # 联系作者
        self.action_4.triggered.connect(lambda:self.about()) # 关于软件

        self.downdir = 'D:\\' #默认下载路径
        self.downfilename = ''
        self.TrueUrl = '' #真正的下载视频地址
        self.title = '' #视频标题
        self.size = '' #视频大小
        self.progressBar.setValue(0) #进度条默认值

        self.progressChanged.connect(self.progressBar.setValue)
        self.charudb.connect(self.charu)
        self.tips.connect(partial(self.tanchuang, '下载完成'))
        # self.label_5.setOpenExternalLinks(True) #将标签的 setOpenExternalLinks(True) 方法来控制与外部的连接 False 才能激活点击信号
        # self.label_5.setToolTip('这是一个超链接标签')
        # self.label_5.setText('<a href="http://www.baidu.com" target="_blank">F:\\pydemo\\Gui_PyQt5</a>')
                #点击文本框绑定槽函数
        self.label_5.setOpenExternalLinks(False)        
        self.label_5.setText('<a href="http://www.baidu.com" target="_blank">{}'.format(os.getcwd()))        
        self.label_5.linkActivated.connect(self.openml) #打开当前目录

        self.label_6.setOpenExternalLinks(False)        
        self.label_6.setText('<a href="http://www.baidu.com" target="_blank">{}'.format(self.downdir))        
        self.label_6.linkActivated.connect(self.opendown) #打开视频下载目录

        
        #自定义表格宽度
        self.tableWidget.setColumnWidth(0, 70)
        self.tableWidget.setColumnWidth(1, 215)
        self.tableWidget.setColumnWidth(2, 52)

   


        # 设置槽函数
        self.pushButton.clicked.connect(self.scrawl)
        # self.pushButton.clicked.connect(partial(self.showdb, 0))
        self.pushButton_2.clicked.connect(self.clearUrl)
        self.pushButton_3.clicked.connect(self.thread) #下载
        # self.pushButton_4.clicked.connect(self.prepage) #上一页
        # self.pushButton_5.clicked.connect(self.nextpage) #下一页
        # self.pushButton_6.clicked.connect(partial(self.tbnum, 1)) #尾页
        # self.pushButton_7.clicked.connect(self.gotopage) #跳转页数


        #链接sqlite数据库
        self.database = QtSql.QSqlDatabase.addDatabase('QSQLITE')
        self.database.setDatabaseName('db.db') #如果没有该文件则自动创建
        self.database.open()


        
        #状态栏
        self.statusBar=QStatusBar()
        #设置状态栏,类似布局设置
        self.setStatusBar(self.statusBar)
        # self.statusBar.showMessage('实时更新的信息', 0) #状态栏本身显示的信息 第二个参数是信息停留的时间,单位是毫秒,默认是0(0表示在下一个操作来临前一直显示)
        self.comNum = QLabel('  小贴士:双击列表中的视频可以直接打开视频目录.  声明:本软件仅供学习技术交流之用,禁止任何形式的商用.')
        self.baudNum = QLabel('版本号:1.0.0')
 
        self.statusBar.addPermanentWidget(self.comNum, stretch=1)
        self.statusBar.addPermanentWidget(self.baudNum, stretch=0) 

        self.showdb()


    #弹窗
    def tanchuang(self,x):
        w = Message()
        w.msg2(x)


    #抓取文章标题
    def scrawl(self):
        # headers = {
        # 'user-agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36',
        # }
        # # 伪装请求头
        # start_url = self.lineEdit.text()
        # result = requests.get(start_url, headers=headers)
        # result.encoding='utf-8'
        # html = result.text
        # soup = BeautifulSoup(html,'html.parser') 
        # title = soup.find('h1', class_="video-title").find(class_='tit').text
        # self.textBrowser.setText('<br/><font color={}>解析成功>>></font><br/><div>{}</div>'.format('#cc0000',title))
        # self.downfilename = title
        start_url = self.lineEdit.text()
        result = os.popen('you-get --json {}'.format(start_url))
        res = result.buffer.read().decode(encoding='utf8')
        textList=[]
        for line in res.splitlines():  
                print(line) 
                textList.append(line)

        self.title =json.loads(res)['title']
        self.size = json.loads(res)['streams']['flv']['size']
        self.TrueUrl =str(json.loads(res)['streams']['flv']['src']).replace("['",'').replace("']",'') #视频地址    
        self.textBrowser.setText('<br/><font color={}>解析成功>>></font><br/><div>{}</div>'.format('#cc0000',self.title))
        self.downfilename = self.title      

    #线程下载
    def thread(self):
        t = threading.Thread(target=self.downvideo, args=(), name='funciton')
        t.start()

    #下载视频
    def downvideo(self):
        headers = {
        "referer": "{}".format(self.lineEdit.text()),
        'user-agent':"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.84 Safari/537.36",
        }
        # 伪装请求头
        start_url = self.TrueUrl
        result = requests.get(start_url,stream=True, headers=headers)
        # result.encoding='utf-8'
        # data = result.content
        # with open('{}.flv'.format(self.title), 'wb') as f:
        #     thsize = 0
        #     for chunk in result.iter_content(chunk_size=512):
                
        #         if chunk:
        #             thsize = thsize+1

        #             # self.progressBar.setValue(thsize)
        #             f.write(chunk)
        f = open('{}.flv'.format(self.title), "wb")
        # chunk是指定每次写入的大小,每次只写了512byte
        chunk_size = 0
        for chunk in result.iter_content(chunk_size=512):
            chunk_size += 512
            n = math.ceil((chunk_size / self.size)*100)
            if chunk:
                f.write(chunk)
                # self.progressBar.setValue(n) #直接子线程修改主线程的数值会报错
                self.progressChanged.emit(n)
        f.close()
        self.tips.emit(1)  #下载完成提示弹窗  
        self.charudb.emit(2) #插入数据

    



        # directory = r'F:\pydemo'                         #设置下载目录
        # url = 'https://www.bilibili.com/video/av86361699?spm_id_from=333.851.b_7265706f7274466972737431.13'      #需要下载的视频地址
        # sys.argv = ['you-get','-o',directory,url]       #sys传递参数执行下载,就像在命令行一样
        # you_get.main()

    #清除网址
    def clearUrl(self):
        self.lineEdit.setText('')
        self.textBrowser.setText('')

    def openml(self):
        menu= menub.caidan()
        menu.openml()


    def opendown(self):
        path = self.downdir
        print(path)
        os.system("start explorer " + path)

    #菜单-设置保存路径
    def savedir(self):
        menu= menub.caidan()
        url = menu.savedir().replace("/", "\\")
        self.label_6.setText('<a href="http://www.baidu.com" target="_blank">{}'.format(url))
        self.downdir = url

    #菜单-常见问题
    def ask(self):
        menu= menub.caidan()
        menu.ask()

    #菜单-联系作者
    def contact(self):
        menu= menub.caidan()
        menu.contact()   
    
    #菜单-关于软件
    def about(self):
        menu= menub.caidan()
        menu.about()   

    #数据展示在表格上
    def showdb(self):
        query = QSqlQuery()
        if query.exec('select * from person ORDER BY ID  DESC limit 0,10'):
            id_index = query.record().indexOf('id')
            name_index = query.record().indexOf('name')
            age_index = query.record().indexOf('age')
            sex_index = query.record().indexOf('sex')
            db = []
            while query.next():
                id = query.value(id_index)
                name = query.value(name_index)
                age = query.value(age_index) 
                sex = query.value(sex_index)
                db.append((age,name,sex))
        for i in range(len(db)): #i是行数
            self.tableWidget.setItem(i, 0, QTableWidgetItem(str(db[i][0])))
            self.tableWidget.setItem(i, 1, QTableWidgetItem(db[i][1]))
            self.tableWidget.setItem(i, 2, QTableWidgetItem(db[i][2]))

    #插入数据 
    def charu(self):
        query = QSqlQuery()
        the_name = self.downfilename #获取姓名
        the_age = '下载完成' #获取状态
        the_sex = '100' #获取内容框的值
        print('插入数据')
        sql_code ='INSERT INTO person (name,age,sex) VALUES ("{}","{}","{}")'.format(the_name,the_age,the_sex)
        if query.exec_(sql_code):
            print('succeed insert data')  
        self.showdb()    

    #可自定义表格
    def table(self): 
        self.tableWidget.setColumnCount(3)
        self.tableWidget.setRowCount(2)
        j = 0#第几行(从0开始)
        i = 0#第几列(从0开始)
        Value = "test"#内容
        self.tableWidget.setItem(j, i, QTableWidgetItem(Value))#设置j行i列的内容为Value
        self.tableWidget.setColumnWidth(j,80)#设置j列的宽度
        self.tableWidget.setRowHeight(i,50)#设置i行的高度
        self.tableWidget.verticalHeader().setVisible(False)#隐藏垂直表头
        self.tableWidget.horizontalHeader().setVisible(False)#隐藏水平表头
    #表格刷新数据
    def renewtb(self):
        self.showdb()




    #查询数据
    def chaxundb(self):

        query = QSqlQuery()
        if query.exec('select * from person'):
            id_index = query.record().indexOf('id')
            name_index = query.record().indexOf('name')
            age_index = query.record().indexOf('age')
            sex_index = query.record().indexOf('sex')
            nr_index = query.record().indexOf('nr')
            db = []
            while query.next():
                id = query.value(id_index)
                name = query.value(name_index)
                age = query.value(age_index)
                sex = query.value(sex_index)
                nr = query.value(nr_index)
                # print(id,name,age,sex,nr)
                db.append((id,name,age,sex,nr))
            print(db)    


    
    #删除数据 
    def deletedb(self):
        query = QSqlQuery()
        sql_code ='DELETE FROM person WHERE ID = 7'
        if query.exec_(sql_code):
            print('Delete data Success')
        
    #更新数据 
    def update(self):
        query = QSqlQuery()
        sql_code ='UPDATE person SET name = "DUU",age="18",sex="女",nr="哈哈哈从成功了" WHERE ID = 6'
        if query.exec_(sql_code):
            print('succeed update data')
   

#提示信息
#这里是消息提示弹出框的主要代码
class Message(QtWidgets.QWidget):  
    def __init__(self):  
        super().__init__()  
    #消息提示框
    def msg(self):  
        QMessageBox.information(self,"提示框","下载完成")
        # QMessageBox.question(self,"消息框标题","这是一条问答。")
        # QMessageBox.information(self,"消息框标题","这是一条消息。")
    def msg2(self,word):  
        QMessageBox.warning(self,"提示框",word)    



if __name__ == '__main__':
    app = QApplication(sys.argv)
    MainWindow = Mywindow()
    MainWindow.show()
    sys.exit(app.exec_())





 

Ui_video.py

# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file 'f:\pydemo\Gui_Pyqt5\video.ui'
#
# Created by: PyQt5 UI code generator 5.14.1
#
# WARNING! All changes made in this file will be lost!


from PyQt5 import QtCore, QtGui, QtWidgets


class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(810, 470)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.label = QtWidgets.QLabel(self.centralwidget)
        self.label.setEnabled(True)
        self.label.setGeometry(QtCore.QRect(50, 600, 54, 12))
        self.label.setAutoFillBackground(False)
        self.label.setFrameShape(QtWidgets.QFrame.NoFrame)
        self.label.setFrameShadow(QtWidgets.QFrame.Plain)
        self.label.setLineWidth(1)
        self.label.setText("TextLabel")
        self.label.setTextFormat(QtCore.Qt.AutoText)
        self.label.setScaledContents(False)
        self.label.setOpenExternalLinks(False)
        self.label.setObjectName("label")
        self.label_2 = QtWidgets.QLabel(self.centralwidget)
        self.label_2.setGeometry(QtCore.QRect(20, 26, 54, 12))
        self.label_2.setObjectName("label_2")
        self.lineEdit = QtWidgets.QLineEdit(self.centralwidget)
        self.lineEdit.setGeometry(QtCore.QRect(80, 20, 261, 25))
        self.lineEdit.setObjectName("lineEdit")
        self.comboBox = QtWidgets.QComboBox(self.centralwidget)
        self.comboBox.setGeometry(QtCore.QRect(350, 20, 71, 25))
        self.comboBox.setObjectName("comboBox")
        self.comboBox.addItem("")
        self.comboBox.addItem("")
        self.comboBox.addItem("")
        self.comboBox.addItem("")
        self.comboBox.addItem("")
        self.comboBox.addItem("")
        self.comboBox.addItem("")
        self.comboBox.addItem("")
        self.comboBox.addItem("")
        self.pushButton = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton.setGeometry(QtCore.QRect(20, 60, 321, 25))
        self.pushButton.setObjectName("pushButton")
        self.pushButton_2 = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton_2.setGeometry(QtCore.QRect(349, 60, 75, 25))
        self.pushButton_2.setObjectName("pushButton_2")
        self.textBrowser = QtWidgets.QTextBrowser(self.centralwidget)
        self.textBrowser.setGeometry(QtCore.QRect(20, 100, 401, 141))
        self.textBrowser.setObjectName("textBrowser")
        self.pushButton_3 = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton_3.setGeometry(QtCore.QRect(20, 290, 401, 25))
        self.pushButton_3.setObjectName("pushButton_3")
        self.label_3 = QtWidgets.QLabel(self.centralwidget)
        self.label_3.setGeometry(QtCore.QRect(20, 340, 81, 16))
        self.label_3.setObjectName("label_3")
        self.label_4 = QtWidgets.QLabel(self.centralwidget)
        self.label_4.setGeometry(QtCore.QRect(20, 380, 81, 16))
        self.label_4.setObjectName("label_4")
        self.label_5 = QtWidgets.QLabel(self.centralwidget)
        self.label_5.setGeometry(QtCore.QRect(110, 340, 311, 16))
        self.label_5.setMouseTracking(False)
        self.label_5.setObjectName("label_5")
        self.label_6 = QtWidgets.QLabel(self.centralwidget)
        self.label_6.setGeometry(QtCore.QRect(110, 380, 311, 16))
        self.label_6.setObjectName("label_6")
        self.tableWidget = QtWidgets.QTableWidget(self.centralwidget)
        self.tableWidget.setGeometry(QtCore.QRect(430, 20, 361, 327))
        self.tableWidget.setObjectName("tableWidget")
        self.tableWidget.setColumnCount(3)
        self.tableWidget.setRowCount(10)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget.setVerticalHeaderItem(0, item)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget.setVerticalHeaderItem(1, item)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget.setVerticalHeaderItem(2, item)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget.setVerticalHeaderItem(3, item)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget.setVerticalHeaderItem(4, item)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget.setVerticalHeaderItem(5, item)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget.setVerticalHeaderItem(6, item)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget.setVerticalHeaderItem(7, item)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget.setVerticalHeaderItem(8, item)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget.setVerticalHeaderItem(9, item)
        item = QtWidgets.QTableWidgetItem()
        item.setTextAlignment(QtCore.Qt.AlignCenter)
        self.tableWidget.setHorizontalHeaderItem(0, item)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget.setHorizontalHeaderItem(1, item)
        item = QtWidgets.QTableWidgetItem()
        item.setTextAlignment(QtCore.Qt.AlignCenter)
        self.tableWidget.setHorizontalHeaderItem(2, item)
        item = QtWidgets.QTableWidgetItem()
        item.setTextAlignment(QtCore.Qt.AlignCenter)
        self.tableWidget.setItem(0, 0, item)
        item = QtWidgets.QTableWidgetItem()
        item.setTextAlignment(QtCore.Qt.AlignJustify|QtCore.Qt.AlignVCenter)
        self.tableWidget.setItem(0, 2, item)
        self.tableWidget.horizontalHeader().setDefaultSectionSize(112)
        self.tableWidget.horizontalHeader().setMinimumSectionSize(25)
        self.tableWidget.verticalHeader().setDefaultSectionSize(30)
        self.progressBar = QtWidgets.QProgressBar(self.centralwidget)
        self.progressBar.setGeometry(QtCore.QRect(20, 254, 401, 23))
        self.progressBar.setProperty("value", 0)
        self.progressBar.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter)
        self.progressBar.setObjectName("progressBar")
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 810, 23))
        self.menubar.setObjectName("menubar")
        self.menu = QtWidgets.QMenu(self.menubar)
        self.menu.setObjectName("menu")
        self.menu_2 = QtWidgets.QMenu(self.menubar)
        self.menu_2.setObjectName("menu_2")
        self.menu_3 = QtWidgets.QMenu(self.menubar)
        self.menu_3.setObjectName("menu_3")
        MainWindow.setMenuBar(self.menubar)
        self.statusBar = QtWidgets.QStatusBar(MainWindow)
        self.statusBar.setTabletTracking(False)
        self.statusBar.setStatusTip("")
        self.statusBar.setLayoutDirection(QtCore.Qt.LeftToRight)
        self.statusBar.setAutoFillBackground(False)
        self.statusBar.setStyleSheet("border-top:1px solid #919191;")
        self.statusBar.setInputMethodHints(QtCore.Qt.ImhNone)
        self.statusBar.setSizeGripEnabled(False)
        self.statusBar.setObjectName("statusBar")
        MainWindow.setStatusBar(self.statusBar)
        self.action = QtWidgets.QAction(MainWindow)
        self.action.setObjectName("action")
        self.action_2 = QtWidgets.QAction(MainWindow)
        self.action_2.setObjectName("action_2")
        self.action_3 = QtWidgets.QAction(MainWindow)
        self.action_3.setObjectName("action_3")
        self.action_4 = QtWidgets.QAction(MainWindow)
        self.action_4.setObjectName("action_4")
        self.menu.addAction(self.action)
        self.menu_2.addAction(self.action_2)
        self.menu_3.addAction(self.action_3)
        self.menu_3.addAction(self.action_4)
        self.menubar.addAction(self.menu.menuAction())
        self.menubar.addAction(self.menu_2.menuAction())
        self.menubar.addAction(self.menu_3.menuAction())

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "主流网站视频下载工具-DownLoadVideo 1.0 Copyright By DU"))
        self.label_2.setText(_translate("MainWindow", "视频地址"))
        self.comboBox.setItemText(0, _translate("MainWindow", "B站-哔哩哔哩"))
        self.comboBox.setItemText(1, _translate("MainWindow", "斗鱼"))
        self.comboBox.setItemText(2, _translate("MainWindow", "爱奇艺"))
        self.comboBox.setItemText(3, _translate("MainWindow", "荔枝FM"))
        self.comboBox.setItemText(4, _translate("MainWindow", "秒拍"))
        self.comboBox.setItemText(5, _translate("MainWindow", "PPTV聚力"))
        self.comboBox.setItemText(6, _translate("MainWindow", "优酷"))
        self.comboBox.setItemText(7, _translate("MainWindow", "音悦Tai"))
        self.comboBox.setItemText(8, _translate("MainWindow", "AcFun"))
        self.pushButton.setText(_translate("MainWindow", "①解析视频"))
        self.pushButton_2.setText(_translate("MainWindow", "清除网址"))
        self.pushButton_3.setText(_translate("MainWindow", "②下载视频"))
        self.label_3.setText(_translate("MainWindow", "软件保存目录:"))
        self.label_4.setText(_translate("MainWindow", "下载保存目录:"))
        self.label_5.setText(_translate("MainWindow", "F:\\pydemo\\Gui_PyQt5"))
        self.label_6.setText(_translate("MainWindow", "F:\\pydemo\\Gui_PyQt5"))
        item = self.tableWidget.verticalHeaderItem(0)
        item.setText(_translate("MainWindow", "1"))
        item = self.tableWidget.verticalHeaderItem(1)
        item.setText(_translate("MainWindow", "2"))
        item = self.tableWidget.verticalHeaderItem(2)
        item.setText(_translate("MainWindow", "3"))
        item = self.tableWidget.verticalHeaderItem(3)
        item.setText(_translate("MainWindow", "4"))
        item = self.tableWidget.verticalHeaderItem(4)
        item.setText(_translate("MainWindow", "5"))
        item = self.tableWidget.verticalHeaderItem(5)
        item.setText(_translate("MainWindow", "6"))
        item = self.tableWidget.verticalHeaderItem(6)
        item.setText(_translate("MainWindow", "7"))
        item = self.tableWidget.verticalHeaderItem(7)
        item.setText(_translate("MainWindow", "8"))
        item = self.tableWidget.verticalHeaderItem(8)
        item.setText(_translate("MainWindow", "9"))
        item = self.tableWidget.verticalHeaderItem(9)
        item.setText(_translate("MainWindow", "10"))
        item = self.tableWidget.horizontalHeaderItem(0)
        item.setText(_translate("MainWindow", "状态"))
        item = self.tableWidget.horizontalHeaderItem(1)
        item.setText(_translate("MainWindow", "文件名称"))
        item = self.tableWidget.horizontalHeaderItem(2)
        item.setText(_translate("MainWindow", "进度"))
        __sortingEnabled = self.tableWidget.isSortingEnabled()
        self.tableWidget.setSortingEnabled(False)
        self.tableWidget.setSortingEnabled(__sortingEnabled)
        self.menu.setTitle(_translate("MainWindow", "系统配置"))
        self.menu_2.setTitle(_translate("MainWindow", "常见问题"))
        self.menu_3.setTitle(_translate("MainWindow", "联系作者"))
        self.action.setText(_translate("MainWindow", "设置保存路径"))
        self.action_2.setText(_translate("MainWindow", "常见问题"))
        self.action_3.setText(_translate("MainWindow", "联系作者"))
        self.action_4.setText(_translate("MainWindow", "关于软件"))