栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

使用python爬取QQ音乐歌曲相关数据

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

使用python爬取QQ音乐歌曲相关数据

一,项目目标

1.获取 QQ 音乐指定歌手单曲排行指定页数的歌曲的歌名、专辑名、播放链接。

2.根据歌曲的名字,获取歌词

3.根据歌曲名字,获取该歌曲的指定页数评论

4.根据下载的歌词或评论文件生成词云

二,需要的库

主要涉及的库有:requests、json、openpyxl、WordCloud

           三,分析QQ音乐数据 

1.1以歌手华晨宇为例,搜索华晨宇,然后按fn+f12,点击网络,找到XHR中字节数最大的文件

点击标头,获取url

1.2.点击paylode,获得param参数,这里可以看出,query代表歌手的名字,page_num代表页数

1.3.点击预览,这里面可以找到很多该歌手相关的信息,但这里我们只需要找到我们所需要的歌曲名,专辑名和mid即可

 

 1.4.代码实现

    def get_info(self):
        wb = openpyxl.Workbook()# 创建工作薄
        sheet = wb.active# 获取工作薄的活动表

        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 = {#引入 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)#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']) + '.htmlnn'
                # 查找播放链接,把链接赋值给link
                sheet.append([song_name, album, link])
                # 把name、album和link写成列表,用append函数多行写入Excel

        wb.save(name + '个人单曲排行前' + str(page * 20) + '清单.xlsx')
        # 最后保存并命名这个Excel文件
        print('下载成功!n')

 1.5.运行效果

 会在该.py文件同目录下生成相关的excel表格,表格内容如下:

 

2.1.

通过不同歌曲参数对比,发现参数id可能会代表不同的歌曲。那么获取指定歌曲的歌词要先得到指定歌曲的id。

 

2.2

先通过input()输入歌名生成url_1找到该歌曲的“id”参数,再生成url_2获取歌词。

获取id部分代码实现:

    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)

2.3

获取歌词部分代码实现

    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)#headers,可以伪装成浏览器
        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')

2.4.代码运行结果

 

3.1 和歌词爬取一样,都需要先获取指定歌曲的id,再对这首歌曲的评论进行爬取。

 

3.2 代码实现

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

 3.3 运行结果

4.1.定义一个cut()函数,把文件里的每一句话分割成词语

 4.2.打开文件,在与.py文件同目录下保存一张自己想指定词云生成的形状图,我自己是“心.jpg”,实现代码如下:

        with open(self.name + ".txt", encoding="utf-8") as file:  # 打开文件
            text = file.read()  # 读取文件里的内容
            text = cut(text)  #把每一句精准分割成词语
            mask_pic = numpy.array(Image.open("心.jpg"))  # 指定词云形状
            wordcloud = WordCloud(font_path="D:/pycharm/code/code2/msyh.ttc",  # 指定文件的生成路径和词云使用的字体微软雅黑细体
                                  collocations=False,  # 避免词云里的词重复
                                  min_font_size=10,  # 指定词云中字体的最小字号
                                  max_font_size=500,  # 指定词云中字体的最大字号
                                  mask=mask_pic  # 指定词云形状
                                  ).generate(text)  # 向WordCloud对象中加载文本text,产生词云
            # image=wordcloud.to_image()
            # image.show()
            wordcloud.to_file(self.name + '云词图.jpg')  # 把词云保存并命名
        print('生成成功!n')

 4.3.运行结果如下图:

四,完整代码

import requests,openpyxl,html,json
from wordcloud import WordCloud
import jieba
import numpy
import PIL.Image as Image

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

    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']) + '.htmlnn'
                # 查找播放链接,把链接赋值给link
                sheet.append([song_name,album,link])
                # 把name、album和link写成列表,用append函数多行写入Excel
                
        wb.save(name+'个人单曲排行前'+str(page*20)+'清单.xlsx')            
        #最后保存并命名这个Excel文件
        print('下载成功!n')

    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')
    
    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)#将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("心.jpg"))#指定词云形状
            wordcloud = WordCloud(font_path="D:/py/msyh.ttc",#指定文件的生成路径和词云使用的字体微软雅黑细体
            collocations=False,#避免词云里的词重复
            min_font_size=10, #指定词云中字体的最小字号
            max_font_size=500,#指定词云中字体的最大字号
            mask=mask_pic#指定词云形状
            ).generate(text)#向WordCloud对象中加载文本text,产生词云
            #image=wordcloud.to_image()
            #image.show()
            wordcloud.to_file(self.name+'云词图.jpg')  # 把词云保存并命名 
        print('生成成功!n')

qq = QQ()
qq.menu()

 五.总结

 

1.爬取 QQ 音乐比爬取所需信息不在网页源代码,需查看 XHR;

2.通过 XHR 爬取数据一般要使用 json,格式为:

res = requests.get(url)
json = res.json()
list = json[‘’][‘’]…

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/657030.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号