python!实现各大平台(网易,酷狗,qq)音乐爬取和收听,下载,第三次更新

python实现各大平台音乐爬取和收听,下载

先上效果图

这个是新增加的喜爱的歌的界面

image

这个是新增的歌曲详情的界面

image

最近这段时间没什么事干,然后我就把整个播放器的界面重构了,并且修复了一些逻辑性的bug

下面就来解析一下代码

首先是最核心的爬虫部分:

image

    # 爬虫线程
    trigger = pyqtSignal(str)

    def __int__(self):
        # 初始化函数
        super(PAThread, self).__init__()

    def run(self):
        qmut.lock()
        try:
            global paing
            global stop
            global lrcs
            global urls
            global songs
            global name
            global songid
            global proxies
            global pic
            global tryed
            paing = True

            print('搜索软件{}'.format(type))
            print('开始搜索')
            name = name
            headers = {
                'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.110.430.128 Safari/537.36',
                'X-Requested-With': 'XMLHttpRequest'

            }
            urls = []
            songs = []
            pic = []
            lrcs = []
            if int(page) == '' or int(page) < 1:
                pages = 2
            else:
                pages = int(page)
            print(pages)
            if not name == '':


                for a in range(1, pages + 1):
                    if not stop:

                        urlss = ['http://music.9q4.cn/', 'https://defcon.cn/dmusic/', 'http://www.xmsj.org/',
                                 'http://music.laomao.me/']
                        print(tryed)
                        if tryed > 3:

                            tryed = 0
                            url = urlss[tryed]
                        else:
                            url = urlss[tryed]
                        print(urlss[tryed])

                        params = {'input': name,
                                  'filter': 'name',
                                  'type': type,
                                  'page': a
                                  }
                        # 爬虫核心
                        if not stop:
                            try:
                                # 获取json文件
                                res = post(url, params, headers=headers, proxies=proxies)
                                html = res.json()

                                for i in range(0, 10):

                                    try:
                                        # 处理文件
                                        title = jsonpath(html, '$..title')[i]
                                        author = jsonpath(html, '$..author')[i]
                                        url1 = jsonpath(html, '$..url')[i]  # 取下载网址
                                        pick = jsonpath(html, '$..pic')[i]  # 取图片

                                        lrc = jsonpath(html, '$..lrc')[i]
                                        print(title, author)
                                        lrcs.append(lrc)
                                        urls.append(url1)
                                        pic.append(pick)
                                        songs.append(str(title) + ' - ' + str(author))
                                        # self.textEdit.setText(lrc)  # 打印歌词
                                        # print(lrc)
                                    except:
                                        pass
                            except:
                                stop = False
                                paing = False

                            print(urls)
                            print(songs)
                            self.trigger.emit(str('finish'))
                        else:
                            print('stop')
                            self.trigger.emit(str('finish'))
                    else:
                        print('stop')
                        self.trigger.emit(str('clear'))
                        pass

                stop = False
                paing = False
            else:
                self.trigger.emit(str('nothing'))
        except:
            print('爬取歌曲出错')
            self.trigger.emit(str('unfinish'))
            stop = False
            paing = False
        qmut.unlock()

然后就是从爬取的url下载歌曲,由于我设计了多个歌单,所以download类比较复杂,由于篇幅问题,我就不在这里展出了
image

class WorkThread(QThread):
    # 自定义信号对象。参数str就代表这个信号可以传一个字符串
    trigger = pyqtSignal(str)

    def __int__(self):
        # 初始化函数
        super(WorkThread, self).__init__()

    def run(self):
        global to
        global number
        global path
        global downloading
        global pic
        global lrct
        global lrcd
        global picno
        global stopdown
        if bo == 'boing':
            try:
                proxies = {
                    'http': 'http://124.72.109.183:8118',
                    ' Shttp': 'http://49.85.1.79:31666'

                }
                headers = {
                    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36',
                    'X-Requested-With': 'XMLHttpRequest'}
                # 处理图片
                try:
                    try:
                        try:
                            aq = pic[num]
                            aqq = aq.split('/')

                        except:
                            pass

                        if type == 'kugou' and len(aqq) - 1 == 6:
                            aqqe = str(aqq[0]) + str('//') + str(aqq[2]) + str('/') + str(aqq[3]) + str('/') + str(
                                '400') + str('/') + str(aqq[5]) + str('/') + str(aqq[6])
                            print(aqqe)
                        elif type == 'netease' and len(aqq) - 1 == 4:
                            aqn = aq.split('?')
                            b = '?param=500x500'
                            aqqe = (str(aqn[0]) + str(b))
                            print(aqqe)
                        else:
                            aqqe = pic[num]
                        req = get(aqqe)

                        checkfile = open(str(data + '/ls1.png'), 'w+b')
                        for i in req.iter_content(100000):
                            checkfile.write(i)

                        checkfile.close()
                        lsfile = str(data + '/ls1.png')
                        safile = str(data + '/back.png')
                        draw(lsfile, safile)
                        picno = True
                    except:
                        print('图片下载错误')
                        picno = False
                        pass
                    url1 = urls[num]
                    print(url1)
                    number = number + 1
                    path = str(data + '\{}.临时文件'.format(number))
                    headers = {
                        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.110.430.128 Safari/537.36',
                        'X-Requested-With': 'XMLHttpRequest'
                    }
                    # 下载歌曲
                    with get(url1, stream=True, headers=headers) as r, open(path, 'wb') as file:
                        total_size = int(r.headers['content-length'])
                        content_size = 0
                        for content in r.iter_content(chunk_size=1024):
                            if not stopdown:
                                file.write(content)
                                content_size += len(content)
                                plan = (content_size / total_size) * 100
                                # print(int(plan))
                                develop = str(int(plan)) + str('%')
                                self.trigger.emit(str(develop))
                            else:
                                print('stopdown')
                                break

                            stopdown = False

                    to = 'downloadmusic\{}.mp3'.format(songs[num])
                    makedirs('downloadmusic', exist_ok=True)
                except:
                    pass
                try:
                    if bo == 'boing':
                        lrct = []
                        f = lrcs[num]  # 按行读取
                        # print (f)
                        lines = f.split('\n')
                        # print (lines)
                        # 处理歌词
                        if not lines == ['']:
                            for i in lines:
                                if not i == '':
                                    line1 = i.split('[')
                                    try:
                                        line2 = line1[1].split(']')
                                        if line2 == '':
                                            pass
                                        else:
                                            linew = line2[1]
                                            # print(linew)
                                            lrct.append(linew)
                                        self.trigger.emit(str('lrcfinish'))
                                    except:
                                        print('{}的歌词错误'.format(str(line1)))
                                else:
                                    pass
                        else:
                            self.trigger.emit(str('lrcnofinish'))
                            print('没有歌词')
                except:
                    print('歌词错误')

                try:
                    copyfile(path, to)
                except:
                    pass
                downloading = False
                self.trigger.emit(str('finish'))

            except:
                self.trigger.emit(str('nofinish'))
				
	
    def display(self, sd):
		#用于接收返回的参数
        global pause
        global songed
        global urled
        global lrcd
        global timenum

        if sd == 'finish':
            try:
                if bo == 'boing':
                    try:
                        e, x = str(songs[num]).split(' - ')
                        self.label_name.setText(e)
                        self.label_showsinger.setText(x)
                        self.label_showname.setText(e)
                        self.label_singer.setText(x)
                    except:
                        self.label_name.setText(songs[num])
                        self.label_showname.setText(songs[num])
                        self.label_singer.setText('')
                        self.label_showsinger.setText('')

                        pass
                elif bo == 'boed':
                    try:
                        e, x = str(songed[num]).split(' - ')
                        self.label_name.setText(e)
                        self.label_showsinger.setText(x)
                        self.label_showname.setText(e)
                        self.label_singer.setText(x)
                    except:
                        self.label_name.setText(songed[num])
                        self.label_showname.setText(songed[num])
                        pass
                elif bo == 'love':
                    try:
                        e, x = str(loves[num]).split(' - ')
                        self.label_name.setText(e)
                        self.label_showsinger.setText(x)
                        self.label_showname.setText(e)
                        self.label_singer.setText(x)
                    except:
                        self.label_name.setText(loves[num])
                        self.label_showname.setText(loves[num])
                        self.label_singer.setText('')
                        self.label_showsinger.setText('')
                        pass
                try:

                    if not picno:
                        pix_img = QPixmap(str(data + '/backdown.png'))
                        pix = pix_img.scaled(300, 300, Qt.KeepAspectRatio)
                        self.label_picbig.setPixmap(pix)
                        pix = pix_img.scaled(200, 300, Qt.KeepAspectRatio)
                        self.label_smallpic.setPixmap(pix)
                        pix = pix_img.scaled(61, 67, Qt.KeepAspectRatio)
                        self.pushButton.setPixmap(pix)

                    else:
                        pix_img = QPixmap(str(data + '/back.png'))
                        pix = pix_img.scaled(300, 300, Qt.KeepAspectRatio)
                        self.label_picbig.setPixmap(pix)
                        pix = pix_img.scaled(200, 300, Qt.KeepAspectRatio)
                        self.label_smallpic.setPixmap(pix)
                        pix = pix_img.scaled(61, 67, Qt.KeepAspectRatio)
                        self.pushButton.setPixmap(pix)

                except:
                    pix_img = QPixmap(str(data + '/backdown.png'))
                    pix = pix_img.scaled(300, 300, Qt.KeepAspectRatio)
                    self.label_picbig.setPixmap(pix)
                    pix = pix_img.scaled(200, 300, Qt.KeepAspectRatio)
                    self.label_smallpic.setPixmap(pix)
                    pix = pix_img.scaled(61, 67, Qt.KeepAspectRatio)
                    self.pushButton.setPixmap(pix)
                print(str(data + '\{}.临时文件'.format(number)))
                mixer.music.load(str(data + '\{}.临时文件'.format(number)))  # 载入音乐
                mixer.music.play()
                self.console_button_3.setIcon(icon('fa.pause', color='#F76677', font=18))
                pause = False
                try:
                    mp3 = str(data + '\{}.临时文件'.format(number))
                    xx = load(mp3)
                    try:
                        timenum = xx.info.time_secs
                        # print(str(timenum))

                        seconds = timenum
                        m, s = divmod(seconds, 60)
                        h, m = divmod(m, 60)
                        time = "%d:%02d:%02d" % (h, m, s)
                        self.label_2.setText(time)
                    except:
                        print('time error')
                    global start
                    start = True

                except:
                    print('MP3错误,播放失败')

                if bo == 'boing':
                    songed.append(songs[num])
                    urled.append(urls[num])
                    picd.append(pic[num])
                    lrcd.append(lrcs[num])
                    r = 0
                    self.listwidget2.clear()
                    for i in songed:
                        # self.listwidget.addItem(i)#将文件名添加到listWidget

                        self.listwidget2.addItem(i)
                        self.listwidget2.item(r).setForeground(Qt.white)
                        r = r + 1
                else:
                    pass
                # 播放音乐
            except:
                pass
        elif sd == 'nofinish':
            self.label_name.setText('下载错误')
            self.label_singer.setText('')

        elif sd == 'lrcfinish':
            r = 0
            self.listwidget_lrc.clear()
            for i in lrct:
                # self.listwidget_lrc.addItem(i)#将文件名添加到listWidget
                if not i == '\r':
                    self.listwidget_lrc.addItem(i)
                    self.listwidget_lrc.item(r).setForeground(Qt.white)
                    r = r + 1
                else:
                    pass
        elif sd == 'lrcnofinish':
            self.listwidget_lrc.clear()
            self.listwidget_lrc.addItem('纯音乐,请欣赏')
            self.listwidget_lrc.item(0).setForeground(Qt.white)
        else:
            self.label_name.setText('加速下载中,已完成{}'.format(sd))
            self.label_singer.setText('')

        def updateTime(self):
            Gettime = mixer.music.get_pos() // 1000  # 获取播放的时间
            seconds = int(Gettime)  # 对播放的时间进行转换
            currenttime = clck(seconds)

        def timercontorl(self):
            global settime

            Song_length = timenum // 1
            Get_Length = int(float(self.horizontalSlider.maximum()))

            rate = Get_Length / 100
            settime = Song_length * rate
            mixer.music.rewind()  # 恢复播放
            mixer.music.set_pos(settime)  # 设置进度条的进度

下面就是QListwidge的点击和播放模块
image

	#播放函数
    def bofang(self, num):
        print ('try bofang')
        try:
            import urllib
            global pause
            global songs
            global music
            global downloading
            downloading = True
            self.console_button_3.setIcon(qtawesome.icon('fa.pause', color='#F76677', font=18))
            pause = False
            # QMessageBox.information(self, "ListWidget", "你选择了: "+item.text())# 显示出消息提示框
            try:
                pygame.mixer.stop()
            except:
                pass
            pygame.mixer.init()
            try:
                self.Timer = QTimer()
                self.Timer.start(500)
            except:
                pass


            try:
                self.label.setText('下载中')#调用开头的多线程下载歌曲
                self.work = WorkThread()
                self.work.start()
                self.work.trigger.connect(self.display)
            except:
                print ('song download error')
                downloading = False
                pass




        except:
            time.sleep(0.1)
            print ('system error')
            #self.next()
            pass
	#用于接收返回的信号
    def display(self,sd):
        if sd == 'finish':
            self.label.setText(songs[num])
            print ('music\{}.mp3'.format(number))
            pygame.mixer.music.load('music\{}.mp3'.format(number))  # 载入音乐
            pygame.mixer.music.play()
            # 播放音乐
        else:
            self.label.setText('下载错误')

下面是双击播放和上一首还有下一首
image

	#QlistWidget的双击事件
    def change_func(self, listwidget):
        global num
        item = QListWidgetItem(self.listwidget.currentItem())
        print(item.text())
        
        num = int(listwidget.currentRow())
        
        self.label.setText(songs[num])
        print(listwidget.currentRow())
        self.bofang(num)
		
	#下一首按钮
	def nextion(self):

            try:
                    if play == 'shun':
                        print('shuning')
                        self.next()
                    elif play == 'shui':
                        print('shuiing')
                        self.shui()
                    elif play == 'always':
                        print('alwaysing')
                        self.next()

            except:
                print('no')
                pass

	

下面自动播放,有循环,随机和单曲循环,加上下一首,上一首,

	#随机播放
    def shui(self):
        global num
        global songs
        q = int(len(songs) - 1)
        num = int(random.randint(1, q))
        try:
            print('shui')
            pygame.mixer.init()
            self.Timer = QTimer()
            self.Timer.start(500)
            # self.Timer.timeout.connect(self.timercontorl)#时间函数,与下面的进度条和时间显示有关
            self.label.setText(songs[num])
            self.bofang(num) # 播放音乐

        except:
            pass
	#下一首
    def next(self):
        print ('nexting')
        global num
        global songs
        if num == len(songs) - 1:
            print('冇')
            num = 0
        else:
            num = num + 1
        try:
            self.label.setText(songs[num])
            self.bofang(num)
        except:
            print ('next error')
            pass


	#单曲循环
    def always(self):
        try:
            self.bofang(num)
            self.label.setText(songs[num])

        except:
            pass
	#上一首
    def last(self):
        global num
        global songs
        if num == 0:
            print('冇')
            num = len(songs) - 1
        else:
            num = num - 1
        try:
            self.bofang(num)
            self.label.setText(songs[num])

        except:
            pass

下面是播放模式选择和循环判断是否要自动下一首
由于每秒钟判断一次,所以要使用多线程

	'''
		在init里面的循环判断打开方法
	    t1 = threading.Thread(target=self.action)
        t1.setDaemon(True)
        t1.start()
    '''
	#选择播放模式
    def playmode(self):
        global play
        try:
            if play == 'shun':
                play = 'shui'
                print('随机播放')
                self.label2.setText("当前为随机播放")
                try:
                    self.console_button_6.setIcon(qtawesome.icon('fa.random', color='#3FC89C', font=18))
                    print('done')
                except:
                    print('none')
                    pass

                # self.left_shui.setText('切换为单曲循环')
            elif play == 'shui':
                play = 'always'
                print('单曲循环')
                self.label2.setText("当前为单曲循环")
                try:
                    self.console_button_6.setIcon(qtawesome.icon('fa.retweet', color='#3FC89C', font=18))
                    print('done')
                except:
                    print('none')


                # self.left_shui.setText('切换为顺序播放')
            elif play == 'always':
                play = 'shun'
                print('顺序播放')
                self.label2.setText("当前为顺序播放")
                try:
                    self.console_button_6.setIcon(qtawesome.icon('fa.align-center', color='#3FC89C', font=18))
                    print('done')
                except:
                    print('none')

                # self.left_shui.setText('切换为随机播放')
        except:
            print('error')
            pass
	#循环判断
    def action(self):
        a = 1
        global num
        while a < 2:
            # print ('checking')
            try:
                time.sleep(1)
                if not pygame.mixer.music.get_busy() and pause == False and not downloading:
                    if play == 'shun':
                        print('shuning')
                        self.next()
                    elif play == 'shui':
                        print('shuiing')
                        self.shui()
                    elif play == 'always':
                        print('alwaysing')
                        self.always()

            except:
                print('no')
                pass
        else:
            pygame.mixer.music.stop()
posted @ 2021-10-05 08:25  ous  阅读(488)  评论(0编辑  收藏  举报