温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

如何使用python批量下载网易云音乐的免费音乐

发布时间:2020-12-08 09:52:57 来源:亿速云 阅读:374 作者:小新 栏目:编程语言

小编给大家分享一下如何使用python批量下载网易云音乐的免费音乐,希望大家阅读完这篇文章后大所收获,下面让我们一起去探讨吧!


运行效果

如何使用python批量下载网易云音乐的免费音乐

代码

# -*- coding:utf-8 -*- import requests, hashlib, sys, click, re, base64, binascii, json, os from Crypto.Cipher import AES from http import cookiejar """ Website:http://cuijiahua.com Author:Jack Cui Refer:https://github.com/darknessomi/musicbox """ class Encrypyed():	"""	解密算法	"""	def __init__(self):	self.modulus = '00e0b509f6259df8642dbc35662901477df22677ec152b5ff68ace615bb7b725152b3ab17a876aea8a5aa76d2e417629ec4ee341f56135fccf695280104e0312ecbda92557c93870114af6c9d05c4f7f0c3685b7a46bee255932575cce10b424d813cfe4875d3e82047b97ddef52741d546b8e289dc6935b3ece0462db0a22b8e7'	self.nonce = '0CoJUm6Qyw8W8jud'	self.pub_key = '010001'	# 登录加密算法, 基于https://github.com/stkevintan/nw_musicbox脚本实现	def encrypted_request(self, text):	text = json.dumps(text)	sec_key = self.create_secret_key(16)	enc_text = self.aes_encrypt(self.aes_encrypt(text, self.nonce), sec_key.decode('utf-8'))	enc_sec_key = self.rsa_encrpt(sec_key, self.pub_key, self.modulus)	data = {'params': enc_text, 'encSecKey': enc_sec_key}	return data	def aes_encrypt(self, text, secKey):	pad = 16 - len(text) % 16	text = text + chr(pad) * pad	encryptor = AES.new(secKey.encode('utf-8'), AES.MODE_CBC, b'0102030405060708')	ciphertext = encryptor.encrypt(text.encode('utf-8'))	ciphertext = base64.b64encode(ciphertext).decode('utf-8')	return ciphertext	def rsa_encrpt(self, text, pubKey, modulus):	text = text[::-1]	rs = pow(int(binascii.hexlify(text), 16), int(pubKey, 16), int(modulus, 16))	return format(rs, 'x').zfill(256)	def create_secret_key(self, size):	return binascii.hexlify(os.urandom(size))[:16] class Song():	"""	歌曲对象,用于存储歌曲的信息	"""	def __init__(self, song_id, song_name, song_num, song_url=None):	self.song_id = song_id	self.song_name = song_name	self.song_num = song_num	self.song_url = '' if song_url is None else song_url class Crawler():	"""	网易云爬取API	"""	def __init__(self, timeout=60, cookie_path='.'):	self.headers = {	'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': 'http://music.163.com/search/',	'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36'	}	self.session = requests.Session()	self.session.headers.update(self.headers)	self.session.cookies = cookiejar.LWPCookieJar(cookie_path)	self.download_session = requests.Session()	self.timeout = timeout	self.ep = Encrypyed()	def post_request(self, url, params):	"""	Post请求	:return: 字典	"""	data = self.ep.encrypted_request(params)	resp = self.session.post(url, data=data, timeout=self.timeout)	result = resp.json()	if result['code'] != 200:	click.echo('post_request error')	else: return result	def search(self, search_content, search_type, limit=9):	"""	搜索API	:params search_content: 搜索内容	:params search_type: 搜索类型	:params limit: 返回结果数量	:return: 字典.	"""	url = 'http://music.163.com/weapi/cloudsearch/get/web?csrf_token='	params = {'s': search_content, 'type': search_type, 'offset': 0, 'sub': 'false', 'limit': limit}	result = self.post_request(url, params)	return result	def search_song(self, song_name, song_num, quiet=True, limit=9):	"""	根据音乐名搜索	:params song_name: 音乐名	:params song_num: 下载的歌曲数	:params quiet: 自动选择匹配最优结果	:params limit: 返回结果数量	:return: Song独享	"""	result = self.search(song_name, search_type=1, limit=limit)	if result['result']['songCount'] <= 0:	click.echo('Song {} not existed.'.format(song_name))	else:	songs = result['result']['songs']	if quiet:	song_id, song_name = songs[0]['id'], songs[0]['name']	song = Song(song_id=song_id, song_name=song_name, song_num=song_num)	return song	def get_song_url(self, song_id, bit_rate=320000):	"""	获得歌曲的下载地址	:params song_id: 音乐ID<int>.	:params bit_rate: {'MD 128k': 128000, 'HD 320k': 320000}	:return: 歌曲下载地址	"""	url = 'http://music.163.com/weapi/song/enhance/player/url?csrf_token='	csrf = ''	params = {'ids': [song_id], 'br': bit_rate, 'csrf_token': csrf}	result = self.post_request(url, params)	# 歌曲下载地址	song_url = result['data'][0]['url']	# 歌曲不存在	if song_url is None:	click.echo('Song {} is not available due to copyright issue.'.format(song_id))	else:	return song_url	def get_song_by_url(self, song_url, song_name, song_num, folder):	"""	下载歌曲到本地	:params song_url: 歌曲下载地址	:params song_name: 歌曲名字	:params song_num: 下载的歌曲数	:params folder: 保存路径	"""	if not os.path.exists(folder):	os.makedirs(folder)	fpath = os.path.join(folder, str(song_num) + '_' + song_name + '.mp3')	if sys.platform == 'win32' or sys.platform == 'cygwin':	valid_name = re.sub(r'[<>:"/\\|?*]', '', song_name)	if valid_name != song_name:	click.echo('{} will be saved as: {}.mp3'.format(song_name, valid_name))	fpath = os.path.join(folder, str(song_num) + '_' + valid_name + '.mp3')	if not os.path.exists(fpath):	resp = self.download_session.get(song_url, timeout=self.timeout, stream=True)	length = int(resp.headers.get('content-length'))	label = 'Downloading {} {}kb'.format(song_name, int(length/1024))	with click.progressbar(length=length, label=label) as progressbar:	with open(fpath, 'wb') as song_file:	for chunk in resp.iter_content(chunk_size=1024):	if chunk:	song_file.write(chunk)	progressbar.update(1024) class Netease():	"""	网易云音乐下载	"""	def __init__(self, timeout, folder, quiet, cookie_path):	self.crawler = Crawler(timeout, cookie_path)	self.folder = '.' if folder is None else folder	self.quiet = quiet	def download_song_by_search(self, song_name, song_num):	"""	根据歌曲名进行搜索	:params song_name: 歌曲名字	:params song_num: 下载的歌曲数	"""	try:	song = self.crawler.search_song(song_name, song_num, self.quiet)	except:	click.echo('download_song_by_serach error')	# 如果找到了音乐, 则下载	if song != None:	self.download_song_by_id(song.song_id, song.song_name, song.song_num, self.folder)	def download_song_by_id(self, song_id, song_name, song_num, folder='.'):	"""	通过歌曲的ID下载	:params song_id: 歌曲ID	:params song_name: 歌曲名	:params song_num: 下载的歌曲数	:params folder: 保存地址	"""	try:	url = self.crawler.get_song_url(song_id)	# 去掉非法字符	song_name = song_name.replace('/', '')	song_name = song_name.replace('.', '')	self.crawler.get_song_by_url(url, song_name, song_num, folder)	except:	click.echo('download_song_by_id error') if __name__ == '__main__':	timeout = 60	output = 'Musics'	quiet = True	cookie_path = 'Cookie'	netease = Netease(timeout, output, quiet, cookie_path)	music_list_name = 'music_list.txt'	# 如果music列表存在, 那么开始下载	if os.path.exists(music_list_name):	with open(music_list_name, 'r') as f:	music_list = list(map(lambda x: x.strip(), f.readlines()))	for song_num, song_name in enumerate(music_list):	netease.download_song_by_search(song_name,song_num + 1)	else:	click.echo('music_list.txt not exist.')

看完了这篇文章,相信你对如何使用python批量下载网易云音乐的免费音乐有了一定的了解,想了解更多相关知识,欢迎关注亿速云行业资讯频道,感谢各位的阅读!

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI