• 爬取 qq,酷我,千千VIP音乐下


    千千音乐可能是第一次爬(没爬到vip),但后来我成功爬到了qq和酷我的vip音乐

    我觉得难度肯定是qq>kuwo>千千吧

    千千和酷我在 上篇 已经有了就不再重复了这篇详细讲讲qq音乐

    qq音乐

    找到一首歌的播放url

    直接随便搜一首歌点播放进入播放页面

    发现media里面有文件(良心)进入这个url就得到了歌的缓存文件

    def qq_down_load(song_name,song_api):
        '''
                下载qq音乐
            :param song_name:
            :param song_api:
            :return:
            '''
        header = {
            'Cookie': 'pgv_pvi=3067481088; RK=e3RBBI+cEG; ptcz=801320b5ce845608fe88e3486ad8bb364cbc2f4ca7963d4ccb872b462bcb29cc; pgv_pvid=408922362; pac_uid=1_1179502349; tvfe_boss_uuid=6666e170218e6655; luin=o1179502349; lskey=000100004e6d001faafba92cccb55e1606698d10622c8ef379cf57841d9e7fc90004782e8945132b9edd1ffc; pgv_si=s4840030208; pgv_info=ssid=s6065813728; qqmusic_fromtag=66',
            'Referer': 'https://y.qq.com/portal/player.html',
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Safari/537.36'
        }
        res = requests.get(song_api, headers=header)
        res.encoding = res.apparent_encoding
        req = res.content
    
        with open(song_name+'.mp3','wb') as f:
            f.write(req)
        path = os.getcwd()
        print(song_name + '  成功下载到' + path)
        time.sleep(1.5)
        return


    找到url变化参数 id,vkey。

    重复上面的步骤可以找另一首歌发现这个url只有 vkey和m4a前面C400后面的那串字母改变 (盲猜id)

    构造url

    这里就是经验了,一般和id有关的都在歌单里,搜索一下那串字母?(果不其然)

    def get_qq_song_list(key_word,page): # 7
        '''
                得到关键字和page的歌单
            :param key_word:
            :param page:
            :return:
            '''
        #url = 'http://c.y.qq.com/soso/fcgi-bin/client_search_cp?p='+str(page)+'&w='+key_word
    
        url='https://c.y.qq.com/soso/fcgi-bin/client_search_cp?p='+str(page)+'&n=10&w='+key_word
        #其实问号后面的都是参数,不能修改的就是p page,删去参数得到的json文件有微小差别 有的key名字不一样还是最好不要删
        header = {
            'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Safari/537.36',
            'cookie': 'pgv_pvi=3067481088; RK=e3RBBI+cEG; ptcz=801320b5ce845608fe88e3486ad8bb364cbc2f4ca7963d4ccb872b462bcb29cc; pgv_pvid=408922362; pac_uid=1_1179502349; tvfe_boss_uuid=6666e170218e6655; luin=o1179502349; ts_uid=4023961751; lskey=000100004e6d001faafba92cccb55e1606698d10622c8ef379cf57841d9e7fc90004782e8945132b9edd1ffc; pgv_si=s4840030208; pgv_info=ssid=s6065813728; ts_refer=ADTAGh5_playsong; qqmusic_fromtag=66; userAction=1; yq_index=0; yqq_stat=0; yq_playschange=0; yq_playdata=; player_exist=1; yplayer_open=0; ts_last=y.qq.com/n/yqq/song/000pSUIh12A9uO.html',
            'referer': 'https://y.qq.com/portal/search.html',
            'accept - encoding': 'gzip, deflate, br'
            }
        res = requests.get(url, headers=header)
        reg=r'{.*}'
        req=re.findall(reg,res.text)[0]
        #jsonloads 可以把str 变成json文件 十分好用!
        html=json.loads(req)
        song_list = html['data']['song']['list']
        return song_list
    
    
    def get_song_info_from_qq(song_info,tot,qq_song_list):
        '''
            从歌单得到每一首歌的数据
            :param tot:
            :param qq_song_list:
            :return:
            '''
        for song in qq_song_list:
            song_info[tot].name = song['songname']
            song_info[tot].atrist_name = song['singer'][0]['name']
            song_info[tot].song_nameid = song['media_mid']
            song_info[tot].song_keyid=song['songmid']
            song_info[tot].belong = 'qq'
            print(tot, song_info[tot].name,'--------歌手:', song_info[tot].atrist_name)
            tot += 1
        return tot

    找vkey...

    我们现在就是要找到这vkey在哪。目的很明白-->在all里面search vkey

    找到了这个明显加密过的url(有不可见人的秘密),preview看下?

    这次时发现了一个songplay 文件下有vkey purl等重要东西

    发现里面含有vkey,和拼接好的purl 我们接下来就是要找到这个url的变量(下面parameter 有参数)

    排除参数

    不断删去参数打开这个songplay url 直到最简 

     

    发现data后面的数字才是核心(改变其他参数对页面几乎没影响)

    从页面下面的param找到所需参数(data)的含意,然后发现data里面只有有个songmid再变化

    也就是只要找到songmid就可以得到vkey 然后就可以下载了 而我们之前已经得到了songmid

    (songmid<==>vkey) 在找到 C开头的那串东西 然后就可下载了

    发现之前的那个文件里面有我们要找的songmid这样一来就大功造成了

    我开始还盲猜和前面的那个id一样,结果发现不对我太天真了

    下载即可

    def get_qq_song_api(song_nameid,song_keyid): # 6
        '''
                获得qqsong的下载地址
            :param song_nameid:
            :param song_keyid:
            :return:
            '''
        #在mp3文件前面发现这个songplayer文件估计时得到播放器的一个文件,里面有data参数(加密)可以把下面的参数直接拿来用即可
        # 发现里面有 vkey 还有歌给你把vkey拼好的purl 我们只要在加上头就可以得到歌曲播放url了
        data='{"req":{"module":"CDN.SrfCdnDispatchServer","method":"GetCdnDispatch","param":{"guid":"408922362","calltype":0,"userip":""}},"req_0":{"module":"vkey.GetVkeyServer","method":"CgiGetVkey","param":{"guid":"408922362","songmid":["%s"],"songtype":[0],"uin":"1179502349","loginflag":1,"platform":"20"}},"comm":{"uin":1179502349,"format":"json","ct":24,"cv":0}}'%song_keyid
        #url='https://u.y.qq.com/cgi-bin/musicu.fcg?-=getplaysongvkey06394791332780847&g_tk=682368363&loginUin=1179502349&hostUin=0&format=json&inCharset=utf8&outCharset=utf-8&notice=0&platform=yqq.json&needNewCode=0&data='+data
        #发现可以去掉多余的参数仍有我们想要的
        url='https://u.y.qq.com/cgi-bin/musicu.fcg?-=getplaysongvkey777244506080595&g_tk=682368363&loginUin=1179502349&hostUin=0&format=json&inCharset=utf8&outCharset=utf-8&notice=0&platform=yqq.json&needNewCode=0&g_tk=682368363&loginUin=1179502349&hostUin=0&format=json&inCharset=utf8&outCharset=utf-8&notice=0&platform=yqq.json&needNewCode=0&data='+data
        header={'cookie': 'pgv_pvi=3067481088; RK=e3RBBI+cEG; ptcz=801320b5ce845608fe88e3486ad8bb364cbc2f4ca7963d4ccb872b462bcb29cc; pgv_pvid=408922362; pac_uid=1_1179502349; tvfe_boss_uuid=6666e170218e6655; luin=o1179502349; ts_uid=4023961751; lskey=000100004e6d001faafba92cccb55e1606698d10622c8ef379cf57841d9e7fc90004782e8945132b9edd1ffc; pgv_si=s4840030208; pgv_info=ssid=s6065813728; ts_refer=ADTAGh5_playsong; qqmusic_fromtag=66; userAction=1; yqq_stat=0; yq_playschange=0; yq_playdata=; player_exist=1; ts_last=y.qq.com/portal/player.html; yplayer_open=1; yq_index=0',
               'referer': 'https://y.qq.com/portal/player.html',
                'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Safari/537.36'
                }
    
        req=requests.get(url,headers=header).json()
        purl=req['req_0']['data']['midurlinfo'][0]['purl']
    
        #print(purl)
        url = 'http://isure.stream.qqmusic.qq.com/C400'+song_nameid+purl[18:-1]

    完整代码:

    import re
    import requests
    import json
    import pprint
    import os
    import sys
    import time
    '''
    1 找到一首歌的播放url
    2 对比不同的歌找到url变化参数 id。vkey。
    3 在all里面search 非id的东西(vkey...)
    4 这次时发现了一个songplay 文件下有vkey purl等重要东西
    5 不断删去参数打开这个songplay url 直到最简 从地下的param 找到所需参数(data)的 解码 
    6 发现data里面有个songmid 
    7 换不同的歌都找这个文件 发现所需参数只有songmid改变 即可以得到vkey  
    8 也就是只要找到songmid就可以得到vkey 然后就可以下载了
    9 一般在歌单里面可以找到id|songmid 构造 1 的url
    10 下载即可
    
    '''
    class Song_info(object):
        def __init__(self):
            self.name=''
            self.song_nameid=''
            self.song_keyid=''#qq音乐特有
            self.atrist_name=''
            self.belong=''
    def get_qq_song_list(key_word,page): # 7
        '''
                得到关键字和page的歌单
            :param key_word:
            :param page:
            :return:
        '''
        #url = 'http://c.y.qq.com/soso/fcgi-bin/client_search_cp?p='+str(page)+'&w='+key_word
    
        url='https://c.y.qq.com/soso/fcgi-bin/client_search_cp?p='+str(page)+'&n=10&w='+key_word
        #其实问号后面的都是参数,不能修改的就是p page,删去参数得到的json文件有微小差别 有的key名字不一样还是最好不要删
        header = {
            'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Safari/537.36',
            'cookie': 'pgv_pvi=3067481088; RK=e3RBBI+cEG; ptcz=801320b5ce845608fe88e3486ad8bb364cbc2f4ca7963d4ccb872b462bcb29cc; pgv_pvid=408922362; pac_uid=1_1179502349; tvfe_boss_uuid=6666e170218e6655; luin=o1179502349; ts_uid=4023961751; lskey=000100004e6d001faafba92cccb55e1606698d10622c8ef379cf57841d9e7fc90004782e8945132b9edd1ffc; pgv_si=s4840030208; pgv_info=ssid=s6065813728; ts_refer=ADTAGh5_playsong; qqmusic_fromtag=66; userAction=1; yq_index=0; yqq_stat=0; yq_playschange=0; yq_playdata=; player_exist=1; yplayer_open=0; ts_last=y.qq.com/n/yqq/song/000pSUIh12A9uO.html',
            'referer': 'https://y.qq.com/portal/search.html',
            'accept - encoding': 'gzip, deflate, br'
            }
        res = requests.get(url, headers=header)
        reg=r'{.*}'
        req=re.findall(reg,res.text)[0]
        #jsonloads 可以把str 变成json文件 十分好用!
        html=json.loads(req)
        song_list = html['data']['song']['list']
        return song_list
    def get_qq_song_api(song_nameid,song_keyid): # 6
        '''
                获得qqsong的下载地址
            :param song_nameid:
            :param song_keyid:
            :return:
        '''
        #在mp3文件前面发现这个songplayer文件估计时得到播放器的一个文件,里面有data参数(加密)可以把下面的参数直接拿来用即可
        # 发现里面有 vkey 还有歌给你把vkey拼好的purl 我们只要在加上头就可以得到歌曲播放url了
        data='{"req":{"module":"CDN.SrfCdnDispatchServer","method":"GetCdnDispatch","param":{"guid":"408922362","calltype":0,"userip":""}},"req_0":{"module":"vkey.GetVkeyServer","method":"CgiGetVkey","param":{"guid":"408922362","songmid":["%s"],"songtype":[0],"uin":"1179502349","loginflag":1,"platform":"20"}},"comm":{"uin":1179502349,"format":"json","ct":24,"cv":0}}'%song_keyid
        #url='https://u.y.qq.com/cgi-bin/musicu.fcg?-=getplaysongvkey06394791332780847&g_tk=682368363&loginUin=1179502349&hostUin=0&format=json&inCharset=utf8&outCharset=utf-8&notice=0&platform=yqq.json&needNewCode=0&data='+data
        #发现可以去掉多余的参数仍有我们想要的
        url='https://u.y.qq.com/cgi-bin/musicu.fcg?-=getplaysongvkey777244506080595&g_tk=682368363&loginUin=1179502349&hostUin=0&format=json&inCharset=utf8&outCharset=utf-8&notice=0&platform=yqq.json&needNewCode=0&g_tk=682368363&loginUin=1179502349&hostUin=0&format=json&inCharset=utf8&outCharset=utf-8&notice=0&platform=yqq.json&needNewCode=0&data='+data
        header={'cookie': 'pgv_pvi=3067481088; RK=e3RBBI+cEG; ptcz=801320b5ce845608fe88e3486ad8bb364cbc2f4ca7963d4ccb872b462bcb29cc; pgv_pvid=408922362; pac_uid=1_1179502349; tvfe_boss_uuid=6666e170218e6655; luin=o1179502349; ts_uid=4023961751; lskey=000100004e6d001faafba92cccb55e1606698d10622c8ef379cf57841d9e7fc90004782e8945132b9edd1ffc; pgv_si=s4840030208; pgv_info=ssid=s6065813728; ts_refer=ADTAGh5_playsong; qqmusic_fromtag=66; userAction=1; yqq_stat=0; yq_playschange=0; yq_playdata=; player_exist=1; ts_last=y.qq.com/portal/player.html; yplayer_open=1; yq_index=0',
               'referer': 'https://y.qq.com/portal/player.html',
                'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Safari/537.36'
                }
        req=requests.get(url,headers=header).json()
        purl=req['req_0']['data']['midurlinfo'][0]['purl']
    
        #print(purl)
        url = 'http://isure.stream.qqmusic.qq.com/C400'+song_nameid+purl[18:-1]
        return  url
    def qq_down_load(song_name,song_api):
        '''
                下载qq音乐
            :param song_name:
            :param song_api:
            :return:
        '''
        header = {
            'Cookie': 'pgv_pvi=3067481088; RK=e3RBBI+cEG; ptcz=801320b5ce845608fe88e3486ad8bb364cbc2f4ca7963d4ccb872b462bcb29cc; pgv_pvid=408922362; pac_uid=1_1179502349; tvfe_boss_uuid=6666e170218e6655; luin=o1179502349; lskey=000100004e6d001faafba92cccb55e1606698d10622c8ef379cf57841d9e7fc90004782e8945132b9edd1ffc; pgv_si=s4840030208; pgv_info=ssid=s6065813728; qqmusic_fromtag=66',
            'Referer': 'https://y.qq.com/portal/player.html',
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Safari/537.36'
        }
        res = requests.get(song_api, headers=header)
        res.encoding = res.apparent_encoding
        req = res.content
    
        with open(song_name+'.mp3','wb') as f:
            f.write(req)
        path = os.getcwd()
        print(song_name + '  成功下载到' + path)
        time.sleep(1.5)
        return
    def get_song_info_from_qq(song_info,tot,qq_song_list):
        '''
            从歌单得到每一首歌的数据
            :param tot:
            :param qq_song_list:
            :return:
            '''
        for song in qq_song_list:
            song_info[tot].name = song['songname']
            song_info[tot].atrist_name = song['singer'][0]['name']
            song_info[tot].song_nameid = song['media_mid']
            song_info[tot].song_keyid=song['songmid']
            song_info[tot].belong = 'qq'
            print(tot, song_info[tot].name,'--------歌手:', song_info[tot].atrist_name)
            tot += 1
        return tot
    def qq_spider():
        print('-----------------introduction---------------')
        print('---------------程序仅供学习交流-------------')
        print('因涉及到vip音乐下载请不要讨论版权问题
    本程序音乐来源--qq音乐')
        print('输入歌手|歌曲名称可以查找,之后再输入编号即可下载')print('暂不支持同时下载几首歌|音质也不知道是啥(默认?)')
        print('--------------------------------------------')
        key_word=input(' 输入关键字
      ')
        page=0
        global song_info
        song_info=[Song_info() for i in range(10000)]
        global tot
       
        while 1:
            page+=1
            qq_song_list=get_qq_song_list(key_word,page)
            tot=1
            print(qq_song_list)
            get_song_info_from_qq(song_info,tot,qq_song_list)
            #重复选择下载歌曲并下载
    
            while(1):
                download_song=input('输入要下载的一首歌编号 输入pass加载一页 exit 退出程序
    ')
                if download_song=='exit':
                    return
                if download_song=='pass':
                    break
                else:
                    download_song=int(download_song)
                    song_name=song_info[download_song].name
                    song_nameid=song_info[download_song].song_nameid
                    song_keyid=song_info[download_song].song_keyid
                    song_artist=song_info[download_song].atrist_name
                    print(song_name, song_artist,'开始下载')
                    if song_info[download_song].belong=='qq':
                        #qq音乐要两个id 一个是song_nameid 一个是获取vkey的song_keyid
                        print('------正在下载' + song_name + '-------')
                        song_api=get_qq_song_api(song_nameid,song_keyid)
                        qq_down_load(song_name,song_api)
    
    if __name__=='__main__':
        qq_spider()
        time.sleep(1)
    
     

    然而令人失望的是我们能点开的都是免费音乐,经过网站解析后发现付费(vip)试听音乐的下载url和免费音乐不同 它不是C400开头而是R... 开头!!!所以只能通过网站解析来得到下载 试听的url??!!应该找个vip进去找找规律...说不定vip下载和试听的url又不一样。。。

    (既然有这种网站我们为什么还要写爬虫???多此一举呜呜呜)

    网易云的日后再补吧,心好累

    还是酷我音乐最 和谐 啥都不防


    --end--

  • 相关阅读:
    springboot中jpa+lombok
    slf4j管理日志,info和error分开存储,每天一个日志文件
    redis内存策略
    redis持久化策略
    Json与对象之间的转化
    Json--01
    缓存中应注意的问题
    面试中的数据库如何优化?
    公司中服务器部署步骤
    Nginx故障迁移
  • 原文地址:https://www.cnblogs.com/cherrypill/p/12448155.html
Copyright © 2020-2023  润新知