【更新】网*云音乐下载python版
本帖最后由 beichenyulu 于 2018-12-25 09:19 编辑代码篇幅有点长,废话不说,直接上代码,
您的评分,是对我最大的支持
语言:python3
用途:下载云音乐
原理:通过模拟实现网页版搜索、听歌,找到每个音乐的相应播放地址(真实地址),然后进行下载
博客:http://www.heanny.cn
GIT:https://gitee.com/heanny
注意事项:headers中的Cookie必须更换,更换步骤:用浏览器打开网页版的云音乐,然后F12,找到Cookie,然后进行替换,就不会报错了
(网页版:music.heanny.cn)
#!python3
# -*- coding: utf-8 -*-
"""
@author: Heanny
@contact: lzh@heanny.cn
@site:
@software: PyCharm
@file: music.py
@time: 2018/8/8 16:15
"""
import requests, json
import random, math
from Crypto.Cipher import AES
import base64
import codecs
import os
"""
获取歌曲地址:https://music.XXX.com/weapi/song/enhance/player/url?csrf_token=429d8812f4449bb9acb60e7647113999
"""
class Spider(object):
def __init__(self):
self.headers = {
'Accept': '*/*',
'Accept-Encoding': 'gzip, deflate, sdch',
'Accept-Language': 'zh-CN,zh;q=0.8,en;q=0.6',
'Connection': 'keep-alive',
'Content-Type': 'application/x-www-form-urlencoded',
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:58.0) Gecko/20100101 Firefox/58.0',
'Cookie': '_ntes_nnid=2da511387474575b77a1e0a13d6df57e,1527507977129; _ntes_nuid=2da511387474575b77a1e0a13d6df57e; vinfo_n_f_l_n3=2e40f7fc7366d16d.1.0.1527507977156.0.1527508882506; usertrack=ezq0plswU1Wdn48dA1XZAg==; _ga=GA1.2.660826221.1529893720; __f_=1532395985802; _iuqxldmzr_=32; __utmz=94650624.1534308847.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none); WM_TID=Z1Jm%2FrA9KHL%2BHxOBomtGeqTrwVoLDJtd; __utmc=94650624; playerid=19834031; JSESSIONID-WYYY=xMEDtoZO%2BiRzkY3QR%5ChVyupwUBwFivY%2BBAyCPJNlEcmafmm94pa%2BquYglywlQBWN4gKk90XO0Dlx1JCU%2BJ3CmBnV8jHBu5Rzj%2BE%5CcvpBRf%2B%2FI%2BUx71SY5lEsfeJKD6SpzZNCw%2Bae%5Ccnl%5CGv7diN8FZ3Hshs6Bh9Aiooh6sjZkafmwztx%3A1534325997512; __utma=94650624.660826221.1529893720.1534319610.1534324198.4; __utmb=94650624.2.10.1534324198; WM_NI=ZzfxoKxGKsmy3YW9fXsRoCollXv7f8VCQELJt4javuXbEgmayUVzE2FcppvHW174lpq1iEeIUNhLS69AeEf%2B%2Fsf5BGaLSIbLfmBZDUozXUnTXRxo2%2BpZmH79ev2gI8%2FqdTI%3D; WM_NIKE=9ca17ae2e6ffcda170e2e6eeb5ec398bbcbaa8f3549aeaa494e763938aa68dc952f68d8585b77aba95b8baf22af0fea7c3b92a9aa6aa99ee41bc998594f073f18799dae554b18ea1a4ee68b088bad8e534969d9fa6cf42b8eca682f57f9cbe8b88f06bbb8b9a9bc83a86bdc091f54495eff9d5ef7cb3efa7a6e8439792a8add23efb9faba6e521edadaad6c14da3949daae148a6b38ebbc75fada698b6ed609c8eb890b121b486a3a9b633a7aafe88cc34edafacb5cc37e2a3'
}
def __get_songs(self, name):
d = json.dumps(
{"hlpretag": "<span class=\"s-fc7\">", "hlposttag": "</span>", "s": name, "type": "1", "offset": "0",
"total": True, "limit": 30, "csrf_token": ""})
wyy = WangYiYun(d)# 要搜索的歌曲名在这里
data = wyy.get_data()
url = 'https://music.XXX.com/weapi/cloudsearch/get/web?csrf_token='
response = requests.post(url, data=data, headers=self.headers).json()
return response['result']
def __get_mp3(self, id):
d = json.dumps({'ids': "[{}]".format(id), 'br': 320000, 'csrf_token': ""})
wyy = WangYiYun(d)
data = wyy.get_data()
url = 'https://music.XXX.com/weapi/song/enhance/player/url?csrf_token='
response = requests.post(url, data=data, headers=self.headers).json()
print(response['code'])
if response['code'] == -460:
return ''
return response['data']['url']
def __download_mp3(self, url, filename):
"""下载mp3"""
abspath = os.path.abspath('.')# 获取绝对路径
os.chdir(abspath)
response = requests.get(url, headers=self.headers).content
path = os.path.join(abspath, filename)
with open('{}.mp3'.format(filename), 'wb') as f:
f.write(response)
print('下载完毕,可以在{}.mp3查看'.format(path))
def __print_info(self, songs):
"""打印歌曲需要下载的歌曲信息"""
songs_list = []
for num, song in enumerate(songs):
print(num, '歌曲名字:', song['name'], '作者:', song['ar']['name'])
songs_list.append((song['name'], song['id']))
return songs_list
def run(self):
while True:
name = input('请输入你需要下载的歌曲:')
songs = self.__get_songs(name)
if songs['songCount'] == 0:
print('没有搜到此歌曲,请换个关键字')
else:
songs = self.__print_info(songs['songs'])
num = input('请输入需要下载的歌曲,输入左边对应数字即可')
if num == 'q':
pass
else:
url = self.__get_mp3(songs)
if not url:
print('歌曲需要收费,下载失败')
else:
filename = songs
self.__download_mp3(url, filename)
flag = input('如需继续可以按任意键进行搜歌,否则按0结束程序')
if flag == '0':
break
print('程序结束!')
class WangYiYun(object):
def __init__(self, d):
self.d = d
self.e = '010001'
self.f = "00e0b509f6259df8642dbc35662901477df22677ec152b5ff68ace615bb7b725152b3ab17a876aea8a5a" \
"a76d2e417629ec4ee341f56135fccf695280104e0312ecbda92557c93870114af6c9d05c4f7f0c3685b7a46be" \
"e255932575cce10b424d813cfe4875d3e82047b97ddef52741d546b8e289dc6935b3ece0462db0a22b8e7"
self.g = "0CoJUm6Qyw8W8jud"
self.random_text = self.get_random_str()
def get_random_str(self):
"""js中的a函数"""
str = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'
res = ''
for x in range(16):
index = math.floor(random.random() * len(str))
res += str
return res
def aes_encrypt(self, text, key):
iv = '0102030405060708'# 偏移量
pad = 16 - len(text.encode()) % 16# 使加密信息的长度为16的倍数,要不会报下面的错
# 长度是16的倍数还会报错,不能包含中文,要对他进行unicode编码
text = text + pad * chr(pad)# Input strings must be a multiple of 16 in length
encryptor = AES.new(key, AES.MODE_CBC, iv)
msg = base64.b64encode(encryptor.encrypt(text))# 最后还需要使用base64进行加密
return msg
def rsa_encrypt(self, value, text, modulus):
'''进行rsa加密'''
text = text[::-1]
rs = int(codecs.encode(text.encode('utf-8'), 'hex_codec'), 16) ** int(value, 16) % int(modulus, 16)
return format(rs, 'x').zfill(256)
def get_data(self):
# 这个参数加密两次
params = self.aes_encrypt(self.d, self.g)
params = self.aes_encrypt(params.decode('utf-8'), self.random_text)
enc_sec_key = self.rsa_encrypt(self.e, self.random_text, self.f)
return {
'params': params,
'encSecKey': enc_sec_key
}
def main():
spider = Spider()
spider.run()
if __name__ == '__main__':
main()
请输入你需要下载的歌曲:一生所爱
Traceback (most recent call last):
File "D:\development\Anaconda3\lib\site-packages\urllib3\connection.py", line 141, in _new_conn
(self.host, self.port), self.timeout, **extra_kw)
File "D:\development\Anaconda3\lib\site-packages\urllib3\util\connection.py", line 83, in create_connection
raise err
File "D:\development\Anaconda3\lib\site-packages\urllib3\util\connection.py", line 73, in create_connection
sock.connect(sa)
TimeoutError: 由于连接方在一段时间后没有正确答复或连接的主机没有反应,连接尝试失败。
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "D:\development\Anaconda3\lib\site-packages\urllib3\connectionpool.py", line 601, in urlopen
chunked=chunked)
File "D:\development\Anaconda3\lib\site-packages\urllib3\connectionpool.py", line 346, in _make_request
self._validate_conn(conn)
File "D:\development\Anaconda3\lib\site-packages\urllib3\connectionpool.py", line 850, in _validate_conn
conn.connect()
File "D:\development\Anaconda3\lib\site-packages\urllib3\connection.py", line 284, in connect
conn = self._new_conn()
File "D:\development\Anaconda3\lib\site-packages\urllib3\connection.py", line 150, in _new_conn
self, "Failed to establish a new connection: %s" % e)
urllib3.exceptions.NewConnectionError: <urllib3.connection.VerifiedHTTPSConnection object at 0x000001B043BE3E80>: Failed to establish a new connection: 由于连接方在一段时间后没有正确答复或连接的主机没有反应,连接尝试失败。
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "D:\development\Anaconda3\lib\site-packages\requests\adapters.py", line 440, in send
timeout=timeout
File "D:\development\Anaconda3\lib\site-packages\urllib3\connectionpool.py", line 639, in urlopen
_stacktrace=sys.exc_info())
File "D:\development\Anaconda3\lib\site-packages\urllib3\util\retry.py", line 388, in increment
raise MaxRetryError(_pool, url, error or ResponseError(cause))
urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='music.xxx.com', port=443): Max retries exceeded with url: /weapi/cloudsearch/get/web?csrf_token= (Caused by NewConnectionError('<urllib3.connection.VerifiedHTTPSConnection object at 0x000001B043BE3E80>: Failed to establish a new connection: 由于连接方在一段时间后没有正确答复或连接的主机没有反应,连接尝试失败。',))
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\Users\r1-12king\Desktop\1\云音乐下载.py", line 150, in <module>
main()
File "C:\Users\r1-12king\Desktop\1\云音乐下载.py", line 146, in main
spider.run()
File "C:\Users\r1-12king\Desktop\1\云音乐下载.py", line 78, in run
songs = self.__get_songs(name)
File "C:\Users\r1-12king\Desktop\1\云音乐下载.py", line 43, in __get_songs
response = requests.post(url, data=data, headers=self.headers).json()
File "D:\development\Anaconda3\lib\site-packages\requests\api.py", line 112, in post
return request('post', url, data=data, json=json, **kwargs)
File "D:\development\Anaconda3\lib\site-packages\requests\api.py", line 58, in request
return session.request(method=method, url=url, **kwargs)
File "D:\development\Anaconda3\lib\site-packages\requests\sessions.py", line 508, in request
resp = self.send(prep, **send_kwargs)
File "D:\development\Anaconda3\lib\site-packages\requests\sessions.py", line 618, in send
r = adapter.send(request, **kwargs)
File "D:\development\Anaconda3\lib\site-packages\requests\adapters.py", line 508, in send
raise ConnectionError(e, request=request)
requests.exceptions.ConnectionError: HTTPSConnectionPool(host='music.xxx.com', port=443): Max retries exceeded with url: /weapi/cloudsearch/get/web?csrf_token= (Caused by NewConnectionError('<urllib3.connection.VerifiedHTTPSConnection object at 0x000001B043BE3E80>: Failed to establish a new connection: 由于连接方在一段时间后没有正确答复或连 接的主机没有反应,连接尝试失败。',))
反馈一下错误 云深不知处 发表于 2018-9-10 16:56
请输入你需要下载的歌曲:一生所爱
Traceback (most recent call last):
File "D:\development\Anacond ...
亲,你把music.xxx.com改成music.163.com啊啊啊啊啊啊啊 收费的下载不了吗? 感谢分享 感谢分享 拿走测试啦 好难啊 不过还是要谢谢楼主 感谢分享 拿走测试啦 {:1_909:}用什么软件啊 云深不知处 发表于 2018-9-10 16:56
请输入你需要下载的歌曲:一生所爱
Traceback (most recent call last):
File "D:\development\Anacond ...
已做描述,按要求来即可 林夕丶 发表于 2018-9-12 12:58
用什么软件啊
环境:python3,
页:
[1]
2