Python实现网易云音乐歌曲URL获取攻略

 获取歌曲url链接需要知道音乐的id,获取id的方式有很多,像歌单,排行榜等可以直接获得。下面是针对网页版搜索栏,通过歌曲名字获取对应的歌曲id(注:本文代码不全,只列出大概)

import json
import requests,random
import base64
from Crypto.Cipher import AES
import pandas as pd
import math

def set_user_agent():
    USER_AGENTS = [
            "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0; .NET CLR 3.5.30729; .NET CLR 3.0.30729; .NET CLR 2.0.50727; Media Center PC 6.0)",
            "Mozilla/5.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; .NET CLR 1.0.3705; .NET CLR 1.1.4322)",
            "Mozilla/4.0 (compatible; MSIE 7.0b; Windows NT 5.2; .NET CLR 1.1.4322; .NET CLR 2.0.50727; InfoPath.2; .NET CLR 3.0.04506.30)",
            "Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN) AppleWebKit/523.15 (KHTML, like Gecko, Safari/419.3) Arora/0.3 (Change: 287 c9dfb30)",
            "Mozilla/5.0 (X11; U; Linux; en-US) AppleWebKit/527+ (KHTML, like Gecko, Safari/419.3) Arora/0.6",
            "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.2pre) Gecko/20070215 K-Ninja/2.1.1",
            "Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9) Gecko/20080705 Firefox/3.0 Kapiko/3.0",
            "Mozilla/5.0 (X11; Linux i686; U;) Gecko/20070322 Kazehakase/0.4.5",
    ]
    user_agent = random.choice(USER_AGENTS)
    return user_agent

def getsonglist(name):
    c_json ={"hlpretag":"<span class=\"s-fc7\">",
             "hlposttag":"</span>",
             "s":name,
             "type":"1",  #true
             "offset":"0",
             "total":"true",
             "limit":"10",
             "csrf_token":"05594195875"}

    c_json=json.dumps(c_json)
    huoqu=getdata(c_json)
    encSecKey=huoqu.getencSecKey()
    encText=huoqu.getencText()

    url='https://music.163.com/weapi/cloudsearch/get/web?csrf_token=05594195875'
    hd={
        'cookie': 'MUSIC_U=00C0B2C6EC5E96F308AB1C35FC07C3EC3637FB71E35A003A2E5494B9AA35A56BED4184C398FA9EE283E9FDBF6EC7B8460C7FF7AA244AAB03636D1EB0D055B1E8ED58EEA5EE4FE48C56CAD7FED09B9E90098E819233229F4B0DE4D36CCBB1DB03F219D00FDA3DA60B9B8A23014317B7F286AE9B9D8F3F2DF8B5CA52F5057F6E0789B819167FB2BEF2529EC004CF1498EC0AB5A854CA97C3C29D4BCB83C0C7CB2B9EAF4AB4E33353AB4500E9BD3981DA9848BA18AF0B9621733227F54B1E580FCA87EDB86BBAD24EE8D1BCCB1066F76D9F6D4BAF0320CBF1AF7E21BDD74ACB6706D970B4A867663CE53AC9EBD0834F5DB4F8FF8AD0A8D27F5ED6DE980481DDB8D42BB3612A5B21532C92CE1A6FF7813C03A4DCC8474334272736E1F7538558C5BFB7515F8FF62151F34342E94DFB061701B95A0307F506F68BACCD7571E9EE819BE713E225159AAD07A5752D8D16DB7D7377A2EDB8AACAE9FC773BED4D5B4C7DA37E5D18AE5782146D1E1A206C55C34DAE0E',
        'Accept': '*/*',
        'Accept-Encoding': 'gzip,deflate,sdch',
        'Accept-Language': 'zh-CN,zh;q=0.8,gl;q=0.6,zh-TW;q=0.4',
        'Connection': 'keep-alive',
        'Content-Type': 'application/x-www-form-urlencoded',
        'Host': 'music.163.com',
        'Referer': 'https://music.163.com/search/',
        'User-Agent': set_user_agent()
    }

    da={
        'params':encText,
        'encSecKey':encSecKey
    }
    res=requests.post(url,data=da,headers=hd).json()
    song_data=res['result']['songs']
    songname=[]
    songid=[]
    singer=[]
    for song in song_data:
        songname.append(song['name'])
        singer.append(song['ar'][0]['name'])
        songid.append(song['id'])
    df = pd.DataFrame(
        data={
            '歌曲名称':songname,
            '歌手': singer
        }
    )
    print(df)
    n=int(input("请选择歌曲:"))
    z={'歌曲':songname[n],'歌手':singer[n],'歌曲id':songid[n]}
    return z

if __name__ == '__main__':
    name=input("请输入歌曲名称")
    print(getsonglist(name))

上述中的参数需要改变例如MUSIC_U(需要用户登录,在Cookie中找,一般是在靠后的位置),MUSIC_U会过期。params和encSecKey参数是在页面上进行的加密,可以找寻

通过断点追踪可以找到大概是这里,其中详细的加密过程可以继续打断点看,这里就不多说了。大概其中一个是经过两轮的AES加密,另外一个是RSA加密,可以通过Python的第三方库进行加密。参考代码如下

def pkcs7(a):
    length = len(a.encode('utf-8'))
    count = 16 - length % 16
    tianchong = count * chr(count)
    return a + tianchong

class aesjiami:
    def __init__(self,key):   #key="0CoJUm6Qyw8W8jud"   "0CoJUm6Qyw8W8jud"
        self.key=key.encode('utf-8')  #密钥
        self.iv="0102030405060708".encode('utf-8')    #初始向量

    def aes(self,text):
        self.text=pkcs7(text)  #数据填充为16的整数倍
        Aes=AES.new(self.key, AES.MODE_CBC, self.iv)  #密钥,模式,偏移量
        miwen=Aes.encrypt(self.text.encode('utf-8'))  #加密
        result=str(base64.b64encode(miwen), encoding='utf-8')   #64编码
        return result

class rsajiami:   #setMaxDigits(131)设置大数的最大位数为131
    def __init__(self):
        self.s="nihao"

    def RSAEncrypt(self, i, e, n):
        num = pow(int(i[::-1].encode().hex(), 16), int(e, 16), int(n, 16))
        result = format(num, 'x')
        return result

def a (a):  #随机生成16位随机字符
    b = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"  #62个初始字符
    c = ""
    for d in range(a):
        e=random.random()*len(b)
        e=math.floor(e)  #取不超过当前大小的最大整数   该数值不大于61且不小于0
        s=int(e)
        c+=b[s]  #根据值去下标对应的字符返回
    return c

运行结果示例:

获取歌曲后通过ID获取url链接,其中也涉及了两个参数加密,一个Cookie反爬(MUSIC_U,针对不许要VIP的歌曲无需正确,有即可;针对VIP歌曲需要是VIP用户的MUSIC_U),和上面类似,代码如下

import sys
import json
import requests,random
import base64
from Crypto.Cipher import AES
import math

import 网易云获取歌曲信息
#凄美地 436346833  达尔文 2019573476

def pkcs7(a):
    length = len(a.encode('utf-8'))
    count = 16 - length % 16
    tianchong = count * chr(count)
    return a + tianchong

class aesjiami:
    def __init__(self,key):   #key="0CoJUm6Qyw8W8jud"   "0CoJUm6Qyw8W8jud"
        self.key=key.encode('utf-8')  #密钥
        self.iv="0102030405060708".encode('utf-8')    #初始向量

    def aes(self,text):
        self.text=pkcs7(text)  #数据填充为16的整数倍
        Aes=AES.new(self.key, AES.MODE_CBC, self.iv)  #密钥,模式,偏移量
        miwen=Aes.encrypt(self.text.encode('utf-8'))  #加密
        result=str(base64.b64encode(miwen), encoding='utf-8')   #64编码
        return result

class rsajiami:   #setMaxDigits(131)设置大数的最大位数为131
    def __init__(self):
        self.s="nihao"

    def RSAEncrypt(self, i, e, n):
        num = pow(int(i[::-1].encode().hex(), 16), int(e, 16), int(n, 16))
        result = format(num, 'x')
        return result

def a (a):  #随机生成16位随机字符
    b = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"  #62个初始字符
    c = ""
    for d in range(a):
        e=random.random()*len(b)
        e=math.floor(e)  #取不超过当前大小的最大整数   该数值不大于61且不小于0
        s=int(e)
        c+=b[s]  #根据值去下标对应的字符返回
    return c

class getdata:
    def __init__(self,token):
        self.token=token
        self.sandom=a(16)
        self.g="00e0b509f6259df8642dbc35662901477df22677ec152b5ff68ace615bb7b725152b3ab17a876aea8a5aa76d2e417629ec4ee341f56135fccf695280104e0312ecbda92557c93870114af6c9d05c4f7f0c3685b7a46bee255932575cce10b424d813cfe4875d3e82047b97ddef52741d546b8e289dc6935b3ece0462db0a22b8e7"


    def getencText(self):
        a=aesjiami("0CoJUm6Qyw8W8jud")
        #s=a.aes(json.dumps(self.token,separators=(',', ':')))  去除空格
        s=a.aes(self.token)
        x=aesjiami(self.sandom)
        y=x.aes(s)
        return y+'='

    def getencSecKey(self):
        b = rsajiami()
        rs = b.RSAEncrypt(self.sandom,"010001",self.g)
        return rs

def fin(songname):
    url='https://music.163.com/weapi/song/enhance/player/url/v1?csrf_token='
    hd={
        'cookie':'MUSIC_U=00D9E5A701C4CBE2208D2D66D740371C4B670703CD68AEA25EF7DE1A4350A9AC75AA967DA9295B928AA257B9A6B559E3CCC516E962993D0B44BAD876F094523089A003BDF55CF829AF25E2EAED2E54FDC90C93E0ECC5B85A7DBFC62B4FDF644ACCF61814FB1950665873C599937E5B8F6860883677CD9A6D74D8433CBA7AD195773F68B4796E3C623433B3B8934EA8D2A0948E26A142D850CC8A969D191B077BB2B4BFBDB5C1C991B0F48AB978433FA734E5BBC6E1CE1F9B136F667AE1B967F4B058133D5FA6D78A5B1B5D7A95B7421FBEFD811E6051F0409D104554D630D519346A3C5DF9BBFB926015AFE0CF6FDB667C111C294527E80465F08323D5841351E42B79792FD083B3BA98FC62148EF92E94F91A4EEDD12C25AEEB9F8E744C04FCBEA8F06C29C24CAF58904C7E83FDE7546944B96BAEA14C19CF1120F2C63A6D50C2BF5C3812D1754A4362761013C7FFE54B031FCF163AA5154AD6ADBF375B4B0F53D2EE4ED4D3EFCFC5755F8DBEEB797EC8',
        'path':'/weapi/song/enhance/player/url/v1?csrf_token=bc9fe810560f94e43faa84bb9128830c',
        'Accept': '*/*',
        'Accept-Encoding': 'gzip,deflate,sdch',
        'Accept-Language': 'zh-CN,zh;q=0.8,gl;q=0.6,zh-TW;q=0.4',
        'Connection': 'keep-alive',
        'Content-Type': 'application/x-www-form-urlencoded',
        'Host': 'music.163.com',
        'Referer': 'https://music.163.com/search/',
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36 Edg/115.0.1901.188'
    }
    c_json = {"ids":"[25727803]","level":"standard","encodeType":"aac","csrf_token":"05594195875be0ea6afd6d377c24a98e"}
    c_json['ids'] = '[' + songname + ']'
    c_json = json.dumps(c_json)
    huoqu = getdata(c_json)
    encSecKey = huoqu.getencSecKey()
    encText = huoqu.getencText()
    da={
        'params':encText,
        'encSecKey':encSecKey
    }
    res=requests.post(url,data=da,headers=hd).text
    data = json.loads(res)['data']
    finurl=data[0]["url"]
    s = finurl.split('?')[0]
    print(s)
    return s

if __name__ == '__main__':
    fin('442867218')

作者:成为一个句号

物联沃分享整理
物联沃-IOTWORD物联网 » Python实现网易云音乐歌曲URL获取攻略

发表回复