zoukankan      html  css  js  c++  java
  • 利用 Python 一键下载网易云音乐 10W+ 乐库

    如果你常听音乐的话,肯定绕不开网易云,作为一款有情怀的音乐 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] = 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 做下尝试。

    注意:如果你是打算找python高薪工作的话。我建议你多写点真实的企业项目积累经验。不然工作都找不到,当然很多人没进过企业,怎么会存在项目经验呢? 所以你得多找找企业项目实战多练习下撒。如果你很懒不想找,也可以进我的Python交流圈:1156465813。群文件里面有我之前在做开发写过的一些真实企业项目案例。你可以拿去学习,不懂都可以在裙里找我,有空会耐心给你解答下。

    以下内容无用,为本篇博客被搜索引擎抓取使用
    (* ̄︶ ̄)(* ̄︶ ̄)(* ̄︶ ̄)(* ̄︶ ̄)(* ̄︶ ̄)(* ̄︶ ̄)(* ̄︶ ̄)(* ̄︶ ̄)
    python 是干什么的 零基础学 python 要多久 python 为什么叫爬虫
    python 爬虫菜鸟教程 python 爬虫万能代码 python 爬虫怎么挣钱
    python 基础教程 网络爬虫 python python 爬虫经典例子
    python 爬虫
    (* ̄︶ ̄)(* ̄︶ ̄)(* ̄︶ ̄)(* ̄︶ ̄)(* ̄︶ ̄)(* ̄︶ ̄)(* ̄︶ ̄)(* ̄︶ ̄)
    以上内容无用,为本篇博客被搜索引擎抓取使用

  • 相关阅读:
    android WebView 加载html5
    android 摄像头的使用
    android 传感器类 sensor
    关于java的一些东西
    android 网络连接管理机制
    利用Layout实现Button的不规则布局
    Android 推送通知指南(转载)
    android开发小问题随记(附1)
    ubuntu下搭建android开发环境(转载)
    北斗小辣椒双核升级攻略之一
  • 原文地址:https://www.cnblogs.com/shuchongzeishuai/p/13947667.html
Copyright © 2011-2022 走看看