# -*- coding: utf-8 -*- # @Time : 2020/12/2 19:00 # @Software : Sublime Text3 # @Author : 公众号 DGX杂学 import requests import parsel import re from PyQt5.QtGui import QIcon from PyQt5 import QtCore, QtGui, QtWidgets import sys import os from PyQt5.QtWidgets import * import time import threading class Ui_MainWindow(QtWidgets.QMainWindow): def setupUi(self, MainWindow): MainWindow.setObjectName("MainWindow") MainWindow.resize(710, 458) MainWindow.setWindowIcon(QIcon('C:\\Users\\Administrator\\Desktop\\Python项目集\\3.0版本\\logo.ico'))#页面窗口左上角的图标,这里自定义图片路径 self.cwd = os.getcwd() self.centralwidget = QtWidgets.QWidget(MainWindow) self.centralwidget.setObjectName("centralwidget") self.groupBox_2 = QtWidgets.QGroupBox(self.centralwidget) self.groupBox_2.setGeometry(QtCore.QRect(20, 60, 671, 141)) self.groupBox_2.setObjectName("groupBox_2") self.label = QtWidgets.QLabel(self.groupBox_2) self.label.setGeometry(QtCore.QRect(30, 30, 61, 16)) self.label.setObjectName("label") self.lineEdit = QtWidgets.QLineEdit(self.groupBox_2) self.lineEdit.setGeometry(QtCore.QRect(90, 30, 271, 20)) self.lineEdit.setObjectName("lineEdit") self.groupBox = QtWidgets.QGroupBox(self.groupBox_2) self.groupBox.setGeometry(QtCore.QRect(520, 30, 111, 61)) self.groupBox.setObjectName("groupBox") self.comboBox = QtWidgets.QComboBox(self.groupBox) self.comboBox.setGeometry(QtCore.QRect(20, 20, 69, 22)) self.comboBox.setObjectName("comboBox") self.comboBox.addItem("1080p") self.comboBox.addItem("720p") self.comboBox.addItem("420p") self.comboBox.addItem("360p") self.comboBox.currentIndexChanged.connect(self.selectionchange) self.label_2 = QtWidgets.QLabel(self.groupBox_2) self.label_2.setGeometry(QtCore.QRect(10, 70, 81, 20)) self.label_2.setObjectName("label_2") layout=QVBoxLayout() self.btn1=QLabel('') layout.addWidget(self.btn1) self.fileT = QtWidgets.QLineEdit(self.centralwidget) self.fileT.setGeometry(QtCore.QRect(109, 130, 272, 22)) self.fileT.setObjectName("file") self.pushButton = QtWidgets.QPushButton(self.groupBox_2) self.pushButton.setGeometry(QtCore.QRect(370, 70, 81, 21)) self.pushButton.setObjectName("pushButton") self.pushButton_2 = QtWidgets.QPushButton(self.groupBox_2) self.pushButton_2.setGeometry(QtCore.QRect(370, 30, 81, 23)) self.pushButton_2.setStyleSheet("background-color: rgb(85, 255, 0);") self.pushButton_2.setObjectName("pushButton_2") self.groupBox_3 = QtWidgets.QGroupBox(self.centralwidget) self.groupBox_3.setGeometry(QtCore.QRect(20, 210, 671, 71)) self.groupBox_3.setObjectName("groupBox_3") #有textEdit这个键,但是没有显示在GUI页面(即隐藏了,这里主要起到全局传参的作用) self.textEdit = QtWidgets.QTextEdit() self.textEdit.setObjectName("textEdit") self.textEdit_2 = QtWidgets.QTextEdit() self.textEdit_2.setObjectName("textEdit_2") self.progressBar = QtWidgets.QProgressBar(self.groupBox_3) self.progressBar.setGeometry(QtCore.QRect(70, 20, 531, 16)) self.progressBar.setProperty("value", 0) self.progressBar.setObjectName("progressBar") # self.label_3 = QtWidgets.QLabel(self.groupBox_3) # self.label_3.setGeometry(QtCore.QRect(260, 40, 71, 20)) # self.label_3.setObjectName("label_3") self.label_11 = QtWidgets.QLabel(self.centralwidget) self.label_11.setGeometry(QtCore.QRect(300, 250, 71, 20)) self.label_11.setObjectName("label_11") self.label_12 = QtWidgets.QLabel(self.centralwidget) self.label_12.setGeometry(QtCore.QRect(250, 200, 71, 20)) self.label_12.setObjectName("label_12") # self.label_12 = QtWidgets.QLabel(self.centralwidget) # self.label_12.setObjectName("label_12") self.groupBox_4 = QtWidgets.QGroupBox(self.centralwidget) self.groupBox_4.setGeometry(QtCore.QRect(20, 300, 371, 101)) self.groupBox_4.setObjectName("groupBox_4") self.label_4 = QtWidgets.QLabel(self.groupBox_4) self.label_4.setGeometry(QtCore.QRect(20, 30, 331, 16)) self.label_4.setObjectName("label_4") self.label_5 = QtWidgets.QLabel(self.groupBox_4) self.label_5.setGeometry(QtCore.QRect(20, 50, 271, 16)) self.label_5.setObjectName("label_5") self.groupBox_5 = QtWidgets.QGroupBox(self.centralwidget) self.groupBox_5.setGeometry(QtCore.QRect(430, 300, 261, 101)) self.groupBox_5.setObjectName("groupBox_5") self.label_6 = QtWidgets.QLabel(self.groupBox_5) self.label_6.setGeometry(QtCore.QRect(20, 20, 61, 16)) self.label_6.setObjectName("label_6") self.label_7 = QtWidgets.QLabel(self.groupBox_5) self.label_7.setGeometry(QtCore.QRect(20, 40, 121, 16)) self.label_7.setObjectName("label_7") self.label_8 = QtWidgets.QLabel(self.groupBox_5) self.label_8.setGeometry(QtCore.QRect(20, 60, 81, 16)) self.label_8.setObjectName("label_8") self.label_9 = QtWidgets.QLabel(self.groupBox_5) self.label_9.setGeometry(QtCore.QRect(20, 80, 141, 16)) self.label_9.setObjectName("label_9") self.label_10 = QtWidgets.QLabel(self.centralwidget) self.label_10.setGeometry(QtCore.QRect(240, 20, 211, 41)) self.label_10.setObjectName("label_10") MainWindow.setCentralWidget(self.centralwidget) self.menubar = QtWidgets.QMenuBar(MainWindow) self.menubar.setGeometry(QtCore.QRect(0, 0, 710, 23)) self.menubar.setObjectName("menubar") MainWindow.setMenuBar(self.menubar) self.statusbar = QtWidgets.QStatusBar(MainWindow) self.statusbar.setObjectName("statusbar") MainWindow.setStatusBar(self.statusbar) self.pushButton_2.clicked.connect(self.download) self.pushButton_2.clicked.connect(self.ProgressBar) self.pushButton.clicked.connect(self.savepath) self.retranslateUi(MainWindow) QtCore.QMetaObject.connectSlotsByName(MainWindow) def selectionchange(self): #self.label_12.setText(self.comboBox.currentText()) if self.comboBox.currentText() == "1080p": definition = "80" self.textEdit_2.append(definition) elif self.comboBox.currentText() == "720p": definition = "64" self.textEdit_2.append(definition) elif self.comboBox.currentText() == "480p": definition = "32" self.textEdit_2.append(definition) elif self.comboBox.currentText() == "360p": definition = "16" self.textEdit_2.append(definition) def savepath(self): fileName_choose, filetype = QFileDialog.getSaveFileName(self, "文件保存", self.cwd, # 起始路径 Mp4 Files (*.mp4) "Mp4 Files (*.mp4);;FLV Files (*.flv)") if fileName_choose == "": return self.fileT.setText(fileName_choose) self.textEdit.append(fileName_choose)#这里主要是让download()调用这里的保存地址 #进度条目前是假的,即不管下载哪个视频,都是一样的;后期会完善这个问题 def ProgressBar(self): def bar(): self.label_11.setText("下载中...") ur3_1 = self.lineEdit.text()+'2' ur3_2 = re.compile('/video/(.*?)2').findall(ur3_1) #这里可能有问题,加斜杠 ur3_3 = ur3_2[0] #获取bvid ur3_5 = "https://api.bilibili.com/x/player/pagelist?bvid={}&jsonp=jsonp".format(ur3_3) r = requests.get(ur3_5) r.encoding="utf-8" scid = str(r.text) duration = re.compile('"duration":(.*?),"vid"').findall(scid) #获取cid duration2 = int(duration[0]) #0.3M/s mp_flux = duration2*0.3 #视频流量大小取整,这里是估计1080p视频大小 #估计视频下载速度为4m/s numtime = int(mp_flux/0.3) h=numtime//3600 m=(numtime-(h*3600))//60 s=numtime-(3600*h)-(60*m) val = 0 for i in range(1,100): val =val + 1 self.progressBar.setProperty("value",val) time.sleep(numtime/99) st = self.textEdit_2.toPlainText() if st == "下载完成!": self.progressBar.setProperty("value",100) self.label_11.setText("下载完成!") break #self.label_12.setText("预计下载时间") #time.sleep(5) #self.label_12.setText("") thread = threading.Thread(target=bar) thread.start() #这里设置子线程以减少主线程(即你看到的UI页面)的压力,防止页面假死(即“未响应”的字样) def download(self): #这里用到B站官方的两个API接口,本人通过Fiddler抓包工具获取到官方接口 self.label_11.setText("下载中...") url_1 = self.lineEdit.text()+'2' url_2 = re.compile('/video/(.*?)2').findall(url_1) #这里可能有问题,加斜杠 url_3 = url_2[0] #获取bvid url_5 = "https://api.bilibili.com/x/player/pagelist?bvid={}&jsonp=jsonp".format(url_3) r = requests.get(url_5) r.encoding="utf-8" scid = str(r.text) cid = re.compile('"cid":(.*?),"page"').findall(scid) #获取cid cid2 = str(cid[0]) url_4 = "https://api.bilibili.com/x/player/playurl?bvid={}&cid={}&fourk=1&qn={}&type=&otype=json&fnver=0".format(url_3,cid2,self.textEdit_2.toPlainText()) #清晰度暂时不设置 headers2 = { "User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:72.0) Gecko/20100101 Firefox/72.0", "accept":"text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9", "accept-encoding":"gzip, deflate, br", "accept-language":"zh-CN,zh;q=0.9", "referer":"https://api.bilibili.com/", "sec-ch-ua-mobile":"?0", "sec-fetch-dest":"document", "sec-fetch-mode":"navigate", "sec-fetch-site":"cross-site", "sec-fetch-user":"?1", "upgrade-insecure-requests":"1", "cookie":"_uuid=0204C263-C8A7-3E5A-37E0-5952386448CD00423infoc; buvid3=6411E1BB-31BD-44E0-80F0-45EE889CC85953929infoc; sid=kv3d3l2z; rpdid=|(k|k)mY~RJR0J'ulm|lYRlRk; LIVE_BUVID=AUTO5615922228199699; blackside_state=1; CURRENT_FNVAL=80; LNG=zh-CN; _ga=GA1.2.352663241.1602946601; CURRENT_QUALITY=80; DedeUserID=449154488; DedeUserID__ckMd5=1b8a0cef25efa62f; SESSDATA=5ca42809%2C1619341696%2Cfdbdd*a1; bili_jct=b0e59804d632d8c93a8a98d1dd9430d6; bp_video_offset_449154488=458577167186968738; bp_t_offset_449154488=458937875718173787; PVID=2; bfe_id=0c3a1998eda2972db3dbce4811a80de6" }#加入cookie可以下载更高画质的视频,这里的cookie为本人的,你可以换成你自己的 headers = { "User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:72.0) Gecko/20100101 Firefox/72.0", "cookie":"_uuid=0204C263-C8A7-3E5A-37E0-5952386448CD00423infoc; buvid3=6411E1BB-31BD-44E0-80F0-45EE889CC85953929infoc; sid=kv3d3l2z; rpdid=|(k|k)mY~RJR0J'ulm|lYRlRk; LIVE_BUVID=AUTO5615922228199699; blackside_state=1; CURRENT_FNVAL=80; LNG=zh-CN; _ga=GA1.2.352663241.1602946601; CURRENT_QUALITY=80; DedeUserID=449154488; DedeUserID__ckMd5=1b8a0cef25efa62f; SESSDATA=5ca42809%2C1619341696%2Cfdbdd*a1; bili_jct=b0e59804d632d8c93a8a98d1dd9430d6; bp_video_offset_449154488=458577167186968738; bp_t_offset_449154488=458937875718173787; PVID=2; bfe_id=0c3a1998eda2972db3dbce4811a80de6" } #添加cookie可以下载1080p及更高的清晰度 get_url = requests.get(url_4,headers = headers) get_url_2 = str(get_url.text) get_url_3 = re.compile('"url":"(.*?)","backup_url"').findall(get_url_2) URL = str(get_url_3[0]) URL2 = URL.replace("\\u0026","&")#把下载的url转化为json格式 def file(): r = requests.get(URL2,headers = headers2) c = r.content #变为byte流数据 #save_mov=open('{}'.format(self.savepath()),'wb') f=open(self.textEdit.toPlainText(),'wb') f.write(c) f.close() #self.progressBar.setProperty("value",100) self.textEdit_2.append("下载完成!") self.btn1.setText(self.textEdit.toPlainText()) thread = threading.Thread(target=file) thread.start() def retranslateUi(self, MainWindow): _translate = QtCore.QCoreApplication.translate MainWindow.setWindowTitle(_translate("MainWindow", "B站视频下载(DGX)")) self.lineEdit.setPlaceholderText(_translate("MainWindow", "请输入视频的URL")) self.groupBox_2.setTitle(_translate("MainWindow", "填写数据")) self.fileT.setText(_translate("MainWindow", "")) self.label.setText(_translate("MainWindow", "视频地址:")) self.groupBox.setTitle(_translate("MainWindow", "清晰度")) self.label_2.setText(_translate("MainWindow", "保存视频位置:")) self.pushButton.setText(_translate("MainWindow", "选择保存路径")) self.pushButton_2.setText(_translate("MainWindow", "点击下载视频")) self.groupBox_3.setTitle(_translate("MainWindow", "运行状态")) #self.label_3.setText(_translate("MainWindow", "下载进度...")) self.groupBox_4.setTitle(_translate("MainWindow", "说明")) self.label_4.setText(_translate("MainWindow", "1.软件暂时不支持下载视频选集,后期更新后会解决这个问题")) self.label_5.setText(_translate("MainWindow", "2.此软件仅供学习和娱乐,禁止商用和非法用途!")) self.groupBox_5.setTitle(_translate("MainWindow", "关于")) self.label_6.setText(_translate("MainWindow", "作者:DGX")) self.label_7.setText(_translate("MainWindow", "微信公众号:DGX杂学")) self.label_8.setText(_translate("MainWindow", "B站:DGX杂学")) self.label_9.setText(_translate("MainWindow", "开发时间:2020/11/19")) self.label_10.setText(_translate("MainWindow", "<html><head/><body><p><span style=\" font-size:26pt; font-weight:600;\">B站视频下载</span></p></body></html>")) if __name__ == "__main__": import sys app = QtWidgets.QApplication(sys.argv) MainWindow = QtWidgets.QMainWindow() ui = Ui_MainWindow() ui.setupUi(MainWindow) MainWindow.show() sys.exit(app.exec_())
© 著作权归作者所有
举报
发表评论
0/200