网易云音乐相信很多小伙伴都用过,是一个非常不错的音乐播放器。
但是越来越多的歌曲开始加入VIP的行列,甚至听都不能听。这类歌曲我们是很难下载的。
而有些歌曲,虽然可以听,但是下载是需要收费的。这类歌曲可以通过本案例轻松下载。即只要能听,就能下载。
所用到的工具:selenium。需要配置一个谷歌selenium的chromedriver。参见教程:selenium配置谷歌浏览器,chromedriver放置的文件夹
Selenium 是一个用于Web应用程序测试的工具。Selenium测试直接运行在浏览器中,就像真正的用户在操作一样。支持的浏览器包括IE(7, 8, 9, 10, 11),Mozilla Firefox,Safari,Google Chrome,Opera等。这个工具的主要功能包括:测试与浏览器的兼容性——测试你的应用程序看是否能够很好得工作在不同浏览器和操作系统之上。测试系统功能——创建回归测试检验软件功能和用户需求。支持自动录制动作和自动生成 .Net、Java、Perl等不同语言的测试脚本。
本案例中的应用程序界面使用的是python自带的tkinter,它比较简单,容易上手。
所使用的接口:
http://music.163.com/song/media/outer/url?id=1345848098.mp3
只要更改其歌曲id,就能下载对应的歌曲了。
所以本程序主要就是通过selenium模拟用户操作浏览器,获取到歌曲的 id,有了歌曲id,就配合该接口解析出歌曲,最后通过urlretrieve下载保存。
该案例的逻辑一目了然,毫无疑问,它的本质,它的核心,就是获取歌曲的 id。
获取歌曲 id:
url = 'https://music.163.com/#/search/m/?s={}&type=1'.format(name)
driver = webdriver.Chrome() #这是不隐藏浏览器的
driver.get(url=url)
driver.switch_to.frame('g_iframe') #有: frame id name index
req = driver.find_element_by_id('m-search')
# 获取歌曲id,通过xpath语法快速定位那个dom元素
a_id = req.find_element_by_xpath('.//div[@class="item f-cb h-flag "]/div[2]//a').get_attribute('href')
print(a_id) #https://music.163.com/song?id=1345848098
song_id = a_id.split('=')[1]
from tkinter import *
from selenium import webdriver
from urllib.parse import quote
from urllib.request import urlretrieve
import os
# 功能
# https://music.163.com/#/search/m/?s=%E7%BB%BF%E8%89%B2&type=1 (搜索)
# http://music.163.com/song/media/outer/url?id=1345848098.mp3(下载)
# 获取歌曲下载链接,直接下载
def song_load(item):
song_id = item['song_id']
song_msg = item['song_msg']
song_url = 'http://music.163.com/song/media/outer/url?id={}.mp3'.format(song_id)
# 创建一个文件夹
os.makedirs('music',exist_ok=True) #如果该文件夹已经存在,则不创建
path = 'music\{}.mp3'.format(song_msg)
# 提示性消息(日志)
listbox.insert(END,'歌曲:{},正在下载...'.format(song_msg))
# 消息文本框滚动
listbox.see(END)
# 更新
listbox.update()
# 下载
urlretrieve(song_url,path)
# 下载完毕
listbox.insert(END, '恭喜你,{} 下载完毕,快去试着听一听吧'.format(song_msg))
# 消息文本框滚动
listbox.see(END)
# 更新
listbox.update()
# 获取歌曲ID
def get_music_id():
name = entry.get()#获取用户在输入框中输入的内容
# 利用quote函数进行URL编码,将汉字转为Unicode
# name = quote(name) 我们把它注释掉,原因是利用selenium去请求是不需要url编码的,而使用requests就必须添加这行代码
url = 'https://music.163.com/#/search/m/?s={}&type=1'.format(name)
print(url)
# 隐藏浏览器
option = webdriver.ChromeOptions()
option.add_argument('--headless')
driver = webdriver.Chrome(chrome_options=option)
# driver = webdriver.Chrome() #这是不隐藏浏览器的
driver.get(url=url)
driver.switch_to.frame('g_iframe') # frame id name index
req = driver.find_element_by_id('m-search')
# 获取歌曲id
a_id = req.find_element_by_xpath('.//div[@class="item f-cb h-flag "]/div[2]//a').get_attribute('href')
print(a_id) #https://music.163.com/song?id=1345848098
song_id = a_id.split('=')[1]
print(song_id)
# 获取歌曲名称
song_name = req.find_element_by_xpath('.//div[@class="item f-cb h-flag "]/div[2]//b').get_attribute('title')
print(song_name)
# 获取歌手名字
singer_name = req.find_element_by_xpath('.//div[@class="item f-cb h-flag "]/div[4]//a').text
print(singer_name)
# 退出浏览器
driver.quit()
# 构建一个字典 id=? msg =?
item = {}
item['song_id'] = song_id
item['song_msg'] = f'{song_name}-{singer_name}'
song_load(item)#下载
# 界面 (tkinter)
#1.创建一张画布(界面)
root = Tk()
#2.添加标题
root.title("网易云音乐下载器")
#3.设置窗口大小
root.geometry('560x450+400+200')
#4.标签控件
label = Label(root,text="请输入歌曲名称:",font=("华文行楷",20))
#5.定位,表格布局,添加控件
label.grid() #默认放置在第一个格子里
#6.输入框
entry = Entry(root,font=("隶书",20))
#7.定位
entry.grid(row=0,column=1)
#8.列表框
listbox = Listbox(root,font=('隶书',16),width=50,height=15)
#9.定位
listbox.grid(row=1,columnspan=2)# columnspan横跨两列
#10.下载按钮
downloadBtn = Button(root,text='开始下载',font=('隶书',15),command=get_music_id)#command=
downloadBtn.grid(row=2,column=0)
#11.退出程序按钮
exitBtn = Button(root,text='退出程序',font=('隶书',15),command=root.quit)
#quit后面一定不要加括号,不加括号意味着该函数在事件触发后才执行
exitBtn.grid(row=2,column=1)
#设置窗口不可拖拽
root.resizable(width=False,height=False)
#消息循环,让界面显示(放在后面写)
root.mainloop()
exe文件:
链接:https://pan.baidu.com/s/1zSte7j6uHvrAMyU0ioMbtw
提取码:t1gu
复制这段内容后打开百度网盘手机App,操作更方便哦