python爬虫---网易云音乐下载

本是古典 何须时尚 2022-03-20 07:56 520阅读 0赞

python爬虫爬取网易云音乐

  • 1.实现功能
  • 2.具体实现
    • 1.搜索部分
    • 2.下载歌曲
      • 1.再次获取信息
      • 2.下载
  • 3.结语

Github完整代码获取:https://github.com/Lian-Zekun/python_spilder

1.实现功能

可以分别对歌名,歌手,歌单进行搜索,搜索歌曲和歌单会列出页面第一页所显示的所有歌曲或歌单及其id以供选择下载,搜索歌手会下载网易云音乐列表显示第一位歌手的所有热门歌曲。

2.具体实现

1.搜索部分

网易云音乐搜索界面为:https://music.163.com/\#/search ,经过测试发现
对单曲搜索时链接为:https://music.163.com/\#/search/m/?s=\{\}&type=1 ,
对歌手搜索时链接为:https://music.163.com/\#/search/m/?s=\{\}&type=100 ,
对歌单搜索时链接为:https://music.163.com/\#/search/m/?s=\{\}&type=1000
其中大括号中内容为要搜索内容的名称,例如搜索年少有为,网址为:https://music.163.com/\#/search/m/?s=年少有为&type=1 搜索后即出现此页面在这里插入图片描述
通过检查元素发现在网页的这一部分存在歌曲链接和名字在这里插入图片描述
同理,在搜索歌单和歌手时检查元素也会发现类似的情况在这里插入图片描述
在这里插入图片描述
虽然分析网易云音乐接口可能会更快的得到这些信息,网上也有很多这样的文章,但菜鸡的我现在对js实在是不懂,选择selenium + chrome 获取js渲染后的页面源码,并通过xpath提取想要的信息(虽然速度是慢了点,但它简单啊)
python代码:

本文导入的所有模块及对爬虫的伪装

  1. import requests
  2. from urllib import request
  3. from lxml import etree
  4. from selenium import webdriver
  5. import platform
  6. import os
  7. import time
  8. headers = {
  9. 'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.81 Safari/537.36',
  10. 'Host': 'music.163.com',
  11. 'Referer': 'https://music.163.com/'
  12. }

通过selenium获得页面源码

  1. def selenium_get_html(url):
  2. """通过selenium获得页面源码"""
  3. # 无界面启动chrome
  4. options = webdriver.ChromeOptions()
  5. options.add_argument(
  6. 'User-Agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.81 Safari/537.36"')
  7. options.add_argument('--headless')
  8. driver = webdriver.Chrome(chrome_options=options)
  9. driver.get(url)
  10. # 歌曲信息在frame框架内,进入frame框架得到源码
  11. driver.switch_to.frame('contentFrame')
  12. return driver.page_source

得到具体信息

  1. # 提取歌曲名称,演唱者姓名,和歌曲id以供选择
  2. def search_input_song(url):
  3. """获取歌曲名字和id"""
  4. html = selenium_get_html(url)
  5. root = etree.HTML(html)
  6. id = root.xpath('//div[@class="srchsongst"]//div[@class="td w0"]//div[@class="text"]/a[1]/@href')
  7. artist = root.xpath('//div[@class="srchsongst"]//div[@class="td w1"]//div[@class="text"]/a[1]/text()')
  8. name = root.xpath('//div[@class="srchsongst"]//div[@class="td w0"]//div[@class="text"]//b/@title')
  9. id = [i.strip('/song?id==') for i in id]
  10. return zip(name, artist, id)
  11. # 歌手默认选择第一位,所以仅得到第一位歌手的id
  12. def search_input_artist(url):
  13. """获取歌手id"""
  14. html = selenium_get_html(url)
  15. root = etree.HTML(html)
  16. id = root.xpath('//div[@class="u-cover u-cover-5"]/a[1]/@href')
  17. return id[0].strip('/artist?id==')
  18. # 提取歌单名称,和歌单id以供选择
  19. def search_input_playlist(url):
  20. """获取歌单名字和id"""
  21. html = selenium_get_html(url)
  22. root = etree.HTML(html)
  23. id = root.xpath('//div[@class="u-cover u-cover-3"]/a/@href')
  24. name = root.xpath('//div[@class="u-cover u-cover-3"]//span/@title')
  25. id = [i.strip('/playlist?id==') for i in id]
  26. return zip(name, id)

2.下载歌曲

1.再次获取信息

得到id信息后,就可以在交互界面提示用户选择id下载。对于单曲来说获取用户选择的id后与对应地址拼接即可进行下载,而对于歌单和歌手因为每一个单位中都存在多首歌曲,第一次仅仅获取了歌手或歌单的id,需要二次分析。我们通过刚刚获取的链接可以发现
单曲的地址为:https://music.163.com/song?id=\{\}
歌手的地址为:https://music.163.com/artist?id=\{\}
歌单的地址为:https://music.163.com/playlist?id=\{\}  ({}内为id)
这回我们进入歌手的页面,检查元素查询歌曲信息,但这次有一个小坑,因为获取的页面中真正的歌曲信息并不在我们检查时看到所在的位置,通过查看框架源代码发现真正的信息在这,歌单页面也是一样。在这里插入图片描述
python代码:

  1. # url为歌单或歌手的地址
  2. def get_url(url):
  3. """从歌单中获取歌曲链接"""
  4. req = requests.get(url, headers=headers)
  5. root = etree.HTML(req.text)
  6. items = root.xpath('//ul[@class="f-hide"]//a')
  7. print(items)
  8. return items

2.下载

通过之前的爬取,我们已经获得了歌曲的id及名称,可以进行下载了
网易云音乐有一个下载外链:https://music.163.com/song/media/outer/url?id=\{\}.mp3
大括号中内容为所下载音乐在网易云的id,所以通过该外链和相应id即可下载网易云音乐。
将id和外链进行拼接后发送get请求,获取get请求所得到页面请求头中’Location’内容,这里面存储的是真正的音乐地址,使用request模块的urlretrieve方法下载。
python代码:

  1. # song_id为歌曲id, song_name为歌曲名称
  2. def download_song(song_id, song_name):
  3. """通过外链下载歌曲"""
  4. url = 'https://music.163.com/song/media/outer/url?id={}.mp3'.format(song_id)
  5. # get请求设置禁止网页跳转,即allow_redirects=False
  6. req = requests.get(url, headers=headers, allow_redirects=False)
  7. song_url = req.headers['Location']
  8. try:
  9. # path在主函数中输入
  10. request.urlretrieve(song_url, path + "/" + song_name + ".mp3")
  11. print("{}--下载完成".format(song_name))
  12. except:
  13. print("{}--下载失败".format(song_name))

3.结语

网易云音乐下载就这么草率的完成了,还有一些瑕疵,因为在写的时候并没有完全构思好,想到什么就加点什么,但绝对可以正常的运行。


本博客文章仅供博主学习交流,博主才疏学浅,语言表达能力有限,对知识的理解、编写代码能力都有很多不足,希望各路大神多多包涵,多加指点。

发表评论

表情:
评论列表 (有 0 条评论,520人围观)

还没有评论,来说两句吧...

相关阅读

    相关 爬虫-音乐视频下载链接

    查看网络请求,如下图,在左边箭头输入框输入mp4,右边链接即为真实的下载链接,不过这个链接有时效性。问题是怎么自己构造这样完整的链接或者能否在网页中找到? ![在这里插入图

    相关 轻松下载音乐中的歌曲

    最近快毕业了,想做一个视频记录一下三年的学习时光,背景音乐准备使用《祝你一路顺风》,找到网易云音乐中的这首曲子,也是原唱,非常满意,但是下载的时候需要安装软件,这就不开心啦,于