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()


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM