beichenyulu 发表于 2018-9-10 15:35

【更新】网*云音乐下载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()

云深不知处 发表于 2018-9-10 16:56

请输入你需要下载的歌曲:一生所爱
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: 由于连接方在一段时间后没有正确答复或连 接的主机没有反应,连接尝试失败。',))


反馈一下错误

beichenyulu 发表于 2018-12-25 09:09

云深不知处 发表于 2018-9-10 16:56
请输入你需要下载的歌曲:一生所爱
Traceback (most recent call last):
File "D:\development\Anacond ...

亲,你把music.xxx.com改成music.163.com啊啊啊啊啊啊啊

云深不知处 发表于 2018-9-10 16:21

收费的下载不了吗?

lucka 发表于 2018-9-10 17:13

感谢分享

枫齐 发表于 2018-9-10 19:39

感谢分享 拿走测试啦

pannide8769 发表于 2018-9-10 21:11

好难啊 不过还是要谢谢楼主

流星的孤单 发表于 2018-9-12 08:30

感谢分享 拿走测试啦

林夕丶 发表于 2018-9-12 12:58

{:1_909:}用什么软件啊

beichenyulu 发表于 2018-9-13 10:57

云深不知处 发表于 2018-9-10 16:56
请输入你需要下载的歌曲:一生所爱
Traceback (most recent call last):
File "D:\development\Anacond ...

已做描述,按要求来即可

beichenyulu 发表于 2018-9-13 10:58

林夕丶 发表于 2018-9-12 12:58
用什么软件啊

环境:python3,
页: [1] 2
查看完整版本: 【更新】网*云音乐下载python版