百度360必应搜狗淘宝本站头条
当前位置:网站首页 > IT知识 > 正文

Python 一键下载网易云音乐 10W+ 乐库

liuian 2025-04-26 19:24 37 浏览

如果你常听音乐的话,肯定绕不开网易云,作为一款有情怀的音乐 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 标签下的 divclass='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] = name
        logger.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] = name
        logger.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 = False
    try:
        with open(download_dir + name + '.mp3', 'wb') as f:
            f.write(r.content)
    except:
        is_fail = True
        logger.info("%s 下载出错" % name)
    if (not is_fail):
        logger.info("%s 下载完成" % name)

最后将所有的操作组合到 main 函数中,作为程序的入口函数。

def main():
    ids = get_topic_ids()
    while True:
        print('')
        logger.info('输入 Q 退出程序')
        logger.info('输入 A 下载全部榜单歌曲')
        logger.info('输入榜单 Id 下载当前榜单歌曲')

        id = input('请输入:')

        if str(id) == 'Q':
            break
        elif str(id) == 'A':
            for id in ids:
                down_song_by_topic_id(id, ids[id])
        else:
            print('')
            ans = get_topic_songs(id, ids[id])
            print('')
            logger.info('输入 Q 退出程序')
            logger.info('输入 A 下载全部歌曲')
            logger.info('输入歌曲 Id 下载当前歌曲')
            id = input('请输入:')
            if str(id) == 'Q':
                break
            elif id == 'A':
                down_song_by_topic_id(id, ans[id])
            else:
                down_song_by_song_id_name(id, ans[id])

if __name__ == "__main__":
    main()

总结

今天我们以网易云网页版为数据源来下载音乐文件,其中下载操作是最简单的,比较麻烦的是分析榜单 id 和获取榜单下的歌曲列表,但榜单下的歌曲列表其实远不止 10 条,而我们获取歌曲的函数 get_topic_songs 每次只可以获取 10 条歌曲,这是因为我们没有在 headers 添加 cookie 导致的,因为只有登录之后才会显示所有的歌曲。小伙伴们可以登录自己的账户然后添加 cookie 做下尝试。

相关推荐

4000台式电脑最好的组装配置
4000台式电脑最好的组装配置

四千元价格组装电脑主机与五千元组装电脑主机的价格类似,因为电脑主机就几个大部件,电脑主机主板是多少代的产品?主板内存的插槽数?电脑处理器等如果是自己组装,都可以配置到十二代产品,电脑硬盘可以分为256G固态硬盘做系统盘,1T机械硬盘作为工作...

2025-11-06 20:05 liuian

linux是一种什么系统(linux属于什么系统)

Linux,全称GNU/Linux,是一种免费使用和自由传播的类UNIX操作系统,是一个基于POSIX的多用户、多任务、支持多线程和多CPU的操作系统。其内核由林纳斯·本纳第克特·托瓦兹于1991年1...

手机管理大师免费版(手机管理大师极速版)

使用手机“文件管理”打开文件夹时提示访问受限,需要前往“文件”应用查看1.进入手机设置——安全——应用权限——权限/应用2.在手机桌面找到手机管家——权限隐私——应用权限——权限/应用?当然,相对于被...

电脑能开机但是进不去桌面怎么办

打开任务管理器按Ctrl+Shift+Esc打开任务管理器。文件中运行新任务点击文件,运行新任务。输入指令重启桌面输入explorer.exe,点击确定,等待桌面重启完成就可以了。电脑已经是我们生活中...

怎样解除自动关机模式(怎样解除自动开关机)

1、打开手机主界面,找到系统自带的“时钟”应用,点击打开它。2、点击进入时钟后,点击右下角的“计时器”。3、进入到计时器后,点击“在计时结束启用雷达”这个选项。4、然后在这里,下拉到最下面,勾选“停...

电脑最高配置是什么配置2025

一,2023最新主流电脑装机配置如下。二,处理器可以使用十二代的i512400或者i512490f,内存16gb双通道,显卡rtx3060,主板可以使用b660m或者h610m。三,如果十三代酷睿...

MySQL慢查询优化:从explain到索引,DBA手把手教你提升10倍性能

数据库性能是应用系统的生命线,而慢查询就像隐藏在系统中的定时炸弹。某电商平台曾因一条未优化的SQL导致订单系统响应时间从200ms飙升至8秒,最终引发用户投诉和订单流失。今天我们就来系统学习MySQL...

一文读懂SQL五大操作类别(DDL/DML/DQL/DCL/TCL)的基础语法

在SQL中,DDL、DML、DQL、DCL、TCL是按操作类型划分的五大核心语言类别,缩写及简介如下:DDL(DataDefinitionLanguage,数据定义语言):用于定义和管理数据库结构...

闲来无事,学学Mysql增、删,改,查

Mysql增、删,改,查1“增”——添加数据1.1为表中所有字段添加数据1.1.1INSERT语句中指定所有字段名语法:INSERTINTO表名(字段名1,字段名2,…)VALUES(值1...

数据库:MySQL 高性能优化规范建议

数据库命令规范所有数据库对象名称必须使用小写字母并用下划线分割所有数据库对象名称禁止使用MySQL保留关键字(如果表名中包含关键字查询时,需要将其用单引号括起来)数据库对象的命名要能做到见名识意,...

下载工具合集_下载工具手机版

迅雷,在国内的下载地位还是很难撼动的,所需要用到的地方还挺多。缺点就是不开会员,软件会限速。EagleGet,全能下载管理器,支持HTTP(S)FTPMMSRTSP协议,也可以使用浏览器扩展检测...

mediamtx v1.15.2 更新详解:功能优化与问题修复

mediamtxv1.15.2已于2025年10月14日发布,本次更新在功能、性能优化以及问题修复方面带来了多项改进,同时也更新了部分依赖库并提升了安全性。以下为本次更新的详细内容:...

声学成像仪:泄露监测 “雷达” 方案开启精准防控

声学成像仪背景将声像图与阵列上配装的摄像实所拍的视频图像以透明的方式叠合在一起,就形成了可直观分析被测物产生状态。这种利用声学、电子学和信息处理等技术,变换成人眼可见的图像的技术可以帮助人们直观地认识...

最稳存储方案:两种方法将摄像头接入威联通Qu405,录像不再丢失

今年我家至少被4位邻居敲门,就是为了查监控!!!原因是小区内部监控很早就停止维护了,半夜老有小黄毛掰车门偷东西,还有闲的没事划车的,车主损失不小,我家很早就配备监控了,人来亮灯有一定威慑力,不过监控设...

离岗检测算法_离岗检查内容

一、研发背景如今社会许多岗位是严禁随意脱离岗位的,如塔台、保安室、监狱狱警监控室等等,因为此类行为可能会引起重大事故,而此类岗位监督管理又有一定困难,因此促生了智能视频识别系统的出现。二、产品概述及工...