手把手教你使用Python抓取QQ音樂數據(第四彈)

【一、項目目標】

通過手把手教你使用Python抓取QQ音樂數據(第一彈)我們實現了獲取 QQ 音樂指定歌手單曲排行指定頁數的歌曲的歌名、專輯名、播放鏈接。

通過手把手教你使用Python抓取QQ音樂數據(第二彈)我們實現了獲取 QQ 音樂指定歌曲的歌詞和指定歌曲首頁熱評。

通過手把手教你使用Python抓取QQ音樂數據(第三彈)我們實現了獲取更多評論並生成詞雲圖。

此次我們將將三個項目封裝在一起,通過菜單控制爬取不同數據。

【二、需要的庫】

主要涉及的庫有:requests、openpyxl、html、json、wordcloud、jieba

如需更換詞雲圖背景圖片還需要numpy庫和PIL庫(pipinstall pillow)

如需生成.exe需要pyinstaller -F

【三、項目實現】

1.首先確定菜單,要實現哪些功能:

①獲取指定歌手的歌曲信息(歌名、專輯、鏈接)

②獲取指定歌曲歌詞

③獲取指定歌曲評論

④生成詞雲圖

⑤退出系統

代碼如下:

<code>class QQ():
    def menu(self):
        print('歡迎使用QQ音樂爬蟲系統,以下是功能菜單,請選擇。\n')
        while True:
            try:
                print('功能菜單\n1.獲取指定歌手的歌曲信息\n2.獲取指定歌曲歌詞\n3.獲取指定歌曲評論\n4.生成詞雲圖\n5.退出系統\n')
                choice = int(input('請輸入數字選擇對應的功能:'))
                if choice == 1:
                    self.get_info()
                elif choice == 2:
                    self.get_id()
                    self.get_lyric()
                elif choice == 3:
                    self.get_id()
                    self.get_comment()
                elif choice == 4:
                    self.wordcloud()
                elif choice == 5:
                    print('感謝使用!')
                    break
                else:
                    print('輸入錯誤,請重新輸入。\n')
            except:
                print('輸入錯誤,請重新輸入。\n')  
/<code>

第一行創建類,第二行定義菜單函數,這裡用了類的實例化,裡面所有函數的第一個參數都是self,我認為實例化更方便傳參數;

whiletrue使菜單無限循環;

Try...except...使循環不會因報錯而退出;

其他代碼為設置輸入不同數字對應打開不同函數。

2.封裝項目(一)為get_info()

代碼如下:

<code>def get_info(self):
        wb=openpyxl.Workbook()  
        #創建工作薄
        sheet=wb.active 
        #獲取工作薄的活動表
        sheet.title='song' 
        #工作表重命名
 
        sheet['A1'] ='歌曲名'     #加表頭,給A1單元格賦值
        sheet['B1'] ='所屬專輯'   #加表頭,給B1單元格賦值
        sheet['C1'] ='播放鏈接'   #加表頭,給C1單元格賦值
        url = 'https://c.y.qq.com/soso/fcgi-bin/client_search_cp'
        name = input('請輸入要查詢的歌手姓名:')
        page = int(input('請輸入需要查詢的歌曲頁數:'))
        for x in range(page):
            params = {
            'ct':'24',
            'qqmusic_ver': '1298',
            'new_json':'1',
            'remoteplace':'sizer.yqq.song_next',
            'searchid':'64405487069162918',
            't':'0',
            'aggr':'1',
            'cr':'1',
            'catZhida':'1',
            'lossless':'0',
            'flag_qc':'0',
            'p':str(x+1),
            'n':'20',
            'w':name,
            'g_tk':'5381',
            'loginUin':'0',
            'hostUin':'0',
            'format':'json',
            'inCharset':'utf8',
            'outCharset':'utf-8',
            'notice':'0',
            'platform':'yqq.json',
            'needNewCode':'0'    
            }
            res = requests.get(url,params=params)
            json = res.json()
            list = json['data']['song']['list']
            for music in list:
                song_name = music['name']
                # 查找歌曲名,把歌曲名賦值給song_name
                album = music['album']['name']
                # 查找專輯名,把專輯名賦給album
                link = 'https://y.qq.com/n/yqq/song/' + str(music['mid']) + '.html\n\n'
                # 查找播放鏈接,把鏈接賦值給link
                sheet.append([song_name,album,link])
                # 把name、album和link寫成列表,用append函數多行寫入Excel
                
        wb.save(name+'個人單曲排行前'+str(page*20)+'清單.xlsx')            
        #最後保存並命名這個Excel文件
        print('下載成功!\n')
/<code> 

3.封裝項目(二)為get_id()和get_lyric

代碼如下:

<code>def get_id(self):
        self.i = input('請輸入歌曲名:')
        url_1 = 'https://c.y.qq.com/soso/fcgi-bin/client_search_cp'
        # 這是請求歌曲評論的url
        headers = {'user-agent':'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36'}
        params = {'ct': '24', 'qqmusic_ver': '1298', 'new_json': '1', 'remoteplace': 'txt.yqq.song', 'searchid': '71600317520820180', 't': '0', 'aggr': '1', 'cr': '1', 'catZhida': '1', 'lossless': '0', 'flag_qc': '0', 'p': '1', 'n': '10', 'w': self.i, 'g_tk': '5381', 'loginUin': '0', 'hostUin': '0', 'format': 'json', 'inCharset': 'utf8', 'outCharset': 'utf-8', 'notice': '0', 'platform': 'yqq.json', 'needNewCode': '0'}  
        res_music = requests.get(url_1,headers=headers,params=params)
        json_music = res_music.json()
        self.id = json_music['data']['song']['list'][0]['id']
        # print(self.id)
 
    def get_lyric(self):
        url_2 = 'https://c.y.qq.com/lyric/fcgi-bin/fcg_query_lyric_yqq.fcg'
        # 這是請求歌曲評論的url
        headers = {
        'origin':'https://y.qq.com',
        'referer':'https://y.qq.com/n/yqq/song/001qvvgF38HVc4.html',
        'user-agent':'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36'}
        params = {
            'nobase64':'1',
            'musicid':self.id,
            '-':'jsonp1',
            'g_tk':'5381',
            'loginUin':'0',
            'hostUin':'0',
            'format':'json',
            'inCharset':'utf8',
            'outCharset':'utf-8',
            'notice':'0',
            'platform':'yqq.json',
            'needNewCode':'0',
            }
        res_music = requests.get(url_2,headers=headers,params=params)
        js_1 = res_music.json()
        lyric = js_1['lyric']
        lyric_html = html.unescape(lyric)   #用了轉義字符html.unescape方法
        # print(lyric_html)
        f1 = open(self.i+'歌詞.txt','a',encoding='utf-8')    #存儲到txt中
        f1.writelines(lyric_html)
        f1.close()
        print('下載成功!\n')
/<code>

這裡特別說一下下載歌詞的headers裡必須加上’origin’和’referer’,要不爬下來數據。

4.封裝項目(三)為get_comment()和wordcloud()

代碼如下:

<code>def get_comment(self):
        page = input('請輸入要下載的評論頁數:')
        url_3 = 'https://c.y.qq.com/base/fcgi-bin/fcg_global_comment_h5.fcg'
        headers = {'user-agent':'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36'}
        f2 = open(self.i+'評論.txt','a',encoding='utf-8')    #存儲到txt中
        for n in range(int(page)):
            params = {'g_tk_new_20200303': '5381', 'g_tk': '5381', 'loginUin': '0', 'hostUin': '0', 'format': 'json', 'inCharset': 'utf8', 'outCharset': 'GB2312', 'notice': '0', 'platform': 'yqq.json', 'needNewCode': '0', 'cid': '205360772', 'reqtype': '2', 'biztype': '1', 'topid': self.id, 'cmd': '6', 'needmusiccrit': '0', 'pagenum':n, 'pagesize': '15', 'lasthotcommentid':'', 'domain': 'qq.com', 'ct': '24', 'cv': '10101010'}
            res_music = requests.get(url_3,headers=headers,params=params)
            js_2 = res_music.json()
            comments = js_2['comment']['commentlist']
            for i in comments:
                comment = i['rootcommentcontent'] + '\n——————————————————————————————————\n'
                f2.writelines(comment)
            # print(comment)
        f2.close()
        print('下載成功!\n')
 
    def wordcloud(self):
        self.name = input('請輸入要生成詞雲圖的文件名稱:')
        def cut(text):
            wordlist_jieba=jieba.cut(text)
            space_wordlist=" ".join(wordlist_jieba)
            return space_wordlist
        with open(self.name+".txt" ,encoding="utf-8")as file:
            text=file.read()
            text=cut(text)
            mask_pic=numpy.array(Image.open("心.png"))
            wordcloud = WordCloud(font_path="C:/Windows/Fonts/simfang.ttf",
            collocations=False,
            max_words= 100,
            min_font_size=10, 
            max_font_size=500,
            mask=mask_pic).generate(text)
            wordcloud.to_file(self.name+'雲詞圖.png')  # 把詞雲保存下來 
        print('生成成功!\n')
/<code>

5.最後類的實例化

<code>qq = QQ()
qq.menu()
/<code>

6.效果展示

手把手教你使用Python抓取QQ音樂數據(第四彈)

image

手把手教你使用Python抓取QQ音樂數據(第四彈)

image

手把手教你使用Python抓取QQ音樂數據(第四彈)

image

手把手教你使用Python抓取QQ音樂數據(第四彈)

image

手把手教你使用Python抓取QQ音樂數據(第四彈)

image

手把手教你使用Python抓取QQ音樂數據(第四彈)

image

手把手教你使用Python抓取QQ音樂數據(第四彈)

image

手把手教你使用Python抓取QQ音樂數據(第四彈)

image

手把手教你使用Python抓取QQ音樂數據(第四彈)

image

手把手教你使用Python抓取QQ音樂數據(第四彈)

image

  1. 打包成.exe

用pyinstaller -F打包,運行會報錯、閃退。

手把手教你使用Python抓取QQ音樂數據(第四彈)

image

看上圖報錯信息應該和詞雲圖有關,註釋掉詞雲圖所需的庫,def wordcloud()按下圖修改可正常打包,但是就沒有生成詞雲圖的功能了:

手把手教你使用Python抓取QQ音樂數據(第四彈)

image

手把手教你使用Python抓取QQ音樂數據(第四彈)

image

手把手教你使用Python抓取QQ音樂數據(第四彈)

image

下載歌詞或評論時,如有重名的歌曲,可在歌曲前面加上歌手姓名,如上圖的“鄧紫棋泡沫”。

【四、總結】

1.項目四對前三個項目進行了複習,在鞏固了爬蟲知識點的同時又複習了類的相關用法;

2.前三個項目可自行戳;文章進行學習:手把手教你使用Python抓取QQ音樂數據(第一彈)、手把手教你使用Python抓取QQ音樂數據(第二彈)、手把手教你使用Python抓取QQ音樂數據(第三彈)。

3.感謝觀看,寫百行以上的代碼是不是輕輕鬆鬆呢。祝小夥伴們學業有成,工作順利!

4.如果需要本文源碼的話,請在公眾號後臺回覆“QQ音樂”四個字進行獲取,覺得不錯,記得給個star噢。

****看完本文有收穫?請轉發分享給更多的人****


分享到:


相關文章: