网易云怎么下载mp3格式的音乐 网易云怎么下载mp3格式的音乐

如果你常听音乐的话 , 肯定绕不开网易云,作为一款有情怀的音乐 App,我对网易云也是喜爱有加 。虽然说现在都已经是 5G 时代了 , 大家的手机流量都绰绰有余,但在线播放还是不如本地存着音乐文件靠谱,今天我们就用 Python 来一键下载网易云音乐乐库 。
其实下载音乐不难,只需要获取到音乐文件播放的地址就可以通过文件流读取的方式直接下载下来 。那么问题就转化为如何获取音乐文件的播放地址了 。
榜单分析我们可以打开网易云排行榜 https://music.163.com/#/discover/toplist?id=19723756 , 仔细分析我们发现该网页左边一列全是排行榜,每个排行榜都对应这不同的排行榜 ID,具体 ID 是多少,直接调开开发者工具即可清晰的看到 。
由上图我们可以看到榜单是放在一个 class='f-cb' 的 ul 列表里面的,所以只需要获取到该 ul 列表的 li 标签即可 。而对于每一个 li 标签来说,其 data-res-id 属性则是榜单 id,而榜单名称则是属于该 li 标签下的 div 中 class='name' 的 p 标签下的 a 标签的内容 。因此我们获取到 li 标签的集合之后,遍历该集合依次取出榜单 id 和榜单名称即可 。
于是我们有了下面的函数 , 获取所有的榜单,该函数返回值是一个字典,key 为 榜单 id,值为榜单名称 。
url = 'https://music.163.com/discover/toplist'hd = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.111 Safari/537.36'}def get_topic_ids():r = requests.get(url, headers=hd)html = etree.HTML(r.text)nodes = html.xpath("//ul[@class='f-cb']/li")logger.info('{}{}'.format('榜单 ID', '榜单名称'))ans = dict()for node in nodes:id = node.xpath('./@data-res-id')[0]name = node.xpath("./div/p[@class='name']/a/text()")[0]ans[id] = namelogger.info('{}{}'.format(id, name))return ans歌曲分析上面我们获取到了所有的榜单数据 , 那么针对单个榜单来说 , 就是要获取其下的所有歌曲了 。
分析页面原属可知,歌曲列表是在一个 table 中的,但是通过 requests.get(url,headers=hd) 方式获取返回的网页文本内容的话,貌似是获取不到 table 元素的 。于是我们将其返回值输出后做了仔细分析,发现歌曲是在 class="f-hide" 的 ul 标签中 。与获取榜单类似,同样需要先获取所有的 li 标签 , 然后在逐个获取歌曲 id 和歌曲 name 就可以了 。
def get_topic_songs(topic_id, topic_name):params = {'id': topic_id}r = requests.get(url, params=params, headers=hd)html = etree.HTML(r.text)nodes = html.xpath("//ul[@class='f-hide']/li")ans = dict()logger.info('{} 榜单 {} 共有歌曲 {} 首 {}'.format('*' * 10, topic_name, len(nodes), '*' * 10))for node in nodes:id = node.xpath('./a/@href')[0].split('=')[1]name = node.xpath('./a/text()')[0]ans[id] = namelogger.info('{}{}'.format(id, name))return ans同样该函数返回一个字典,key 为歌曲 id,value 为歌曲名称 。
下载歌曲我们还需要一个下载歌曲的函数,该函数接收歌曲 id,然后以文件流的形式直接读取到本地 。
def down_song_by_song_id_name(id, name):if not os.path.exists(download_dir):os.mkdir(download_dir)url = 'http://music.163.com/song/media/outer/url?id={}.mp3'r = requests.get(url.format(id), headers=hd)is_fail = Falsetry:with open(download_dir + name + '.mp3', 'wb') as f:f.write(r.content)except:is_fail = Truelogger.info("%s 下载出错" % name)if (not is_fail):logger.info("%s 下载完成" % name)最后将所有的操作组合到 main 函数中,作为程序的入口函数 。

推荐阅读