scrapy爬取网易云音乐的MP3链接

最近遇到需要从网易云音乐爬取MP3的url的需求,看了很多github以及博客内容,都是直接拿着参数请求抓包得到的url,网上的一些api还能用,但是很多都已经不能用了,而且能用的那些也里面的MP3url也都是空的,无法下载了,但是现在网易云的所有接口,都是经过加密的,参数基本都是params和encSecKey这两个,问题的关键就是这两个参数怎么来的,本篇内容以搜索关键词获取到一个歌单,并且得到每首歌的下载链接为例进行一波学习
首先用浏览器打开网易云音乐进行一波搜索,查看一下network调用情况
这里写图片描述
看到有个url的请求,看下它的response
是一个json,我这里直接放上来不截图了,

{
  "data": [
    {
      "id": 480667963,
      "url": "http://m8.music.126.net/20170716165834/eff1ec73def7e921481f99e90dfcdb3c/ymusic/6a84/17e2/b61a/29cd4fc45e6d290f48a4fb41b1e26483.mp3",
      "br": 128000,
      "size": 10203681,
      "md5": "29cd4fc45e6d290f48a4fb41b1e26483",
      "code": 200,
      "expi": 1200,
      "type": "mp3",
      "gain": 2.7422,
      "fee": 0,
      "uf": null,
      "payed": 0,
      "flag": 0,
      "canExtend": false
    }
  ],
  "code": 200
}

可以看到,里面有后缀为.mp3的url链接,因此,我们只要知道了这个请求的参数,就可以得到歌曲的下载链接了,参数params和encSecKey是一都是一长串经过js加密的字符,所以,我们先去把加密的js找到,没错,就是那个core.js请求得到的js,先下载到本地,用编辑器打开,妈呀,20000万多行害我编辑器都卡了半天
这里写图片描述
吐槽归吐槽,正事要紧,搜索一下我们需要的那两个参数
这里写图片描述
我们可以看到,这两个参数来源于window.asrsea函数加密,这个函数需要4个参数,为了弄清楚这几个参数是什么,我们吧这个js稍作修改,用fiddler去替换掉请求的core.js,执行看一下
这里写图片描述
修改很简单,我只是把这几个参数直接在console打印了一遍,
我搜索的url是
http://music.163.com/#/search/m/?s=%E6%B7%B1%E7%88%B1%E4%B8%80%E4%B8%AA%E4%BA%BA%E4%BC%9A%E5%BE%88%E7%B4%AF%E5%90%97&type=1009
看下console的输出
这里写图片描述
多个url参数的结果看来,4个参数中,有3个参数是定死不会变的,唯一变的就是第一个参数,这是我们每个接口真正需要去请求的参数,另外3个是加密过程中用来加密的参数

参数有了,现在我们要做的就是把这些参数加密成params和encSecKey,然后直接用我们的爬虫带着这两个参数去请求url就可以获取到对应的内容了,下面就去按照js里的加密方法一步步完成加密的过程
找到js里面的window.asrsea,
这里写图片描述
其中的4个参数就是我们上面说到的4个参数
a为
这里写图片描述
b为
这里写图片描述
c为
这里写图片描述
分析一下这个加密逻辑
1、 先生成一个16位随机数i
2、 使用g参数作为key,将动态参数d进行加密得encText (加密函数b(a,b))
3、 使用随机数i作为key,将上步加密得到的encText再次加密(加密函数b(a,b))
4、 使用参数e,f作为key,将随机数i进行加密的encSecKey(加密函数c(a, b, c))

分析完成,开始来写我们的scrapy代码
我们先通过关键字搜个,然后在去请求得到我们的MP3url,第一个请求的url为
http://music.163.com/weapi/cloudsearch/get/web?csrf_token=
这个接口要的参数为(別問我怎麼知道的,再去看上面~)
{
“s”: “深爱一个人会很累吗-蓝七”,
“offset”: 0,
“limit”: 1,
“type”: “1009”,
}
還有total表示是不是在第页以及hlpretag的一个span标签,都不是必须的就不传了,其他几个参数好理解,type由于我搜索的是时光电台的,是1009,如果搜歌或者其他,还得自己去查看一下,接下来,按照我们上面的方法先加一波密,

post_data = {
            "s": "深爱一个人会很累吗-蓝七",
            "offset": 0,
            "limit": 1,
            "type": "1009",
        }
json_data = json.dumps(post_data)
sec_key = create_random_secrekey(16)
enc_text = aes_encrypt(aes_encrypt(json_data, nonce), sec_key)
enc_seckey = rsa_encrypt(sec_key, pubKey, modulus)

其中的几个方法为:

def create_random_secrekey(size):
    return (''.join(map(lambda xx: (hex(ord(xx))[2:]), os.urandom(size))))[0:16]
def aes_encrypt(text, sec_key):
    pad = 16 - len(text) % 16
    text = text + pad * chr(pad)
    encryptor = AES.new(sec_key, 2, '0102030405060708')
    ciphertext = encryptor.encrypt(text)
    ciphertext = base64.b64encode(ciphertext)
    return ciphertext
def rsa_encrypt(text, pubKey, modulus):
    text = text[::-1]
    rs = int(text.encode('hex'), 16) ** int(pubKey, 16) % int(modulus, 16)
    return format(rs, 'x').zfill(256)

几个常量对应着上面说到的3个常量,分别为

nonce = '0CoJUm6Qyw8W8jud'
pubKey = '010001'
modulus = '00e0b509f6259df8642dbc35662901477df22677ec152b5ff68ace615bb7b725152b3ab17a876aea8a5aa76d2e417629ec4ee341f56135fccf695280104e0312ecbda92557c93870114af6c9d05c4f7f0c3685b7a46bee255932575cce10b424d813cfe4875d3e82047b97ddef52741d546b8e289dc6935b3ece0462db0a22b8e7 '

请求结果是一个json,内容一长串我就不贴了,通过去查看获取MP3url的接口参数,我们需要在这个json里拿的参数有歌曲的id和一个叫bitrate的参数,拿好之后,去下一个请求的url为http://music.163.com/weapi/song/enhance/player/url?csrf_token=
同样的加密方式加密参数

{
song_data['ids'] = [text['result']['djprograms'][0]['mainSong']['id']]
song_data['br'] = text['result']['djprograms'][0]['mainSong']['bMusic']['bitrate']
song_data['csrf_token'] = ''
}

最后的结果为

{
  "data": [
    {
      "id": 480667963,
      "url": "http://m8.music.126.net/20170716183944/a425cac854c4e44ce73aa4ec5e0eec5f/ymusic/6a84/17e2/b61a/29cd4fc45e6d290f48a4fb41b1e26483.mp3",
      "br": 128000,
      "size": 10203681,
      "md5": "29cd4fc45e6d290f48a4fb41b1e26483",
      "code": 200,
      "expi": 1200,
      "type": "mp3",
      "gain": 2.7422,
      "fee": 0,
      "uf": null,
      "payed": 0,
      "flag": 0,
      "canExtend": false
    }
  ],
  "code": 200
}

可以测试一下打开这个url,bingo收工

评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值