目录
搭建窗口
爬虫实现下载音乐
歌曲搜索
下载歌曲
绑定命令
生成可执行文件
感想
在前一篇文章,正好总结过了Tkinter以及canvas画布的使用,学以致用,用Tkinter来创建一个窗口,在此基础上实现音乐的下载逻辑,并在最后打包成exe文件。
最近刚好学了Tkinter和Canvas画布,顺便总结了一下,想着那它来做点什么练练手,我平常挺喜欢听音乐,特别是在大型评论APP平台——网易云音乐(滑稽),歌不仅推荐的好,而且评论“个个说话又好听”。所以想着自己做一个音乐下载器,试一试。结果感觉还可以,起码做出来了,就是界面糙了点,功能简陋点,除了能跑,也就没啥优点了。
废话不多说,上一波效果图。

先把源码分享出来吧,放在了我的gitee和CSDN我的下载中,需要的可自取。下面我分享一下我的代码思路。
搭建窗口
搭建窗口就像画画一样,你需要哪些,可以使用tkinter组件像画画一样把它布局到canvas上。把需要的布局想好,设定好,再布局到想要的位置上。
from tkinter import *
# 搭建界面
#创建界面 画板窗口
window = Tk()
#创建标题
window.title('网易云音乐')
# 设置窗口大小和位置
window.geometry('560x450+400+200')
# 标签控件,实现文本和字体及大小
label = Label(window,text='请输入下载的歌曲:',font=('华文行楷',20))
# 标签定位
label.grid()
# 输入框
entry = Entry(window,font=('隶书',20))
# 定位
entry.grid(row=0,column=1)
# 列表框
text = Listbox(window,font=('楷书',16),width=50,height=15)
# 定位 columnspan组件横跨的列数
text.grid(row=1,columnspan=2)
# 点击开始下载按钮
button_start = Button(window,text='开始下载',font=('楷书',15),command='')
# 定位,按钮‘粘着’在西侧(左侧)
button_start.grid(row=2,column=0,sticky=W)
# 点击退出按钮
button_quit = Button(window,text='退出程序',font=('楷书',15),command='')
# 定位
button_quit.grid(row=2,column=1,sticky=E)
# 显示界面
window.mainloop()
说明:
mainloop实现窗口的显示,否则窗口无法显示;
geometry函数参数的含义:('长X宽'),窗口默认出现在屏幕的左上角,修改位置,('长X宽+距左边框距离+距上边框距离');
在label设置标签和entry设置文本框中,定义部分就像画画时我们想好了要画多大的、画在哪,但还没有落笔去画,grid()函数就像是是我们下笔的动作一样,把我们想的在窗口上显示出来;
grid()的参数就像把一张画纸以自适应表格的形式去划分,我要把布局放在哪里就用行和列的形式去摆放;
窗口中核心的部分在于按钮逻辑的设计,即conmand命令所要执行的函数。
运行效果:
爬虫实现下载音乐
-
歌曲搜索
利用爬虫实现下载音乐的功能。打开网易云音乐网页,任意搜索歌曲,F12打开网页源代码,可以找到每首歌独特的歌曲id,就像每个人的身份证一样,是独一无二的,可以定位到每一首歌。
网易云音乐提供了歌曲的外链接口(https://music.163.com/song/media/outer/url?id={}.mp3),于是可以从网页中爬取到歌曲的id,写入外链接口中,进行歌曲的下载。问题就变成了一个爬虫问题,根据歌曲名爬取每个歌曲的id。
但在实际开发过程中,根据搜索想要的歌,但在网易云网页的源代码中却找不到歌名,此时发现这个网页是一个动态网页(静态页面和动态页面的区别),信息都是动态加载出来的,那么爬虫就不能用request爬取静态页面那套了,python中对于动态页面爬虫也有对应的库‘selenium’,其好比一个网页浏览的机器人,伪造一个类似的界面。
from selenium import webdriver
def get_music_name():
url='https://music.163.com/#/search/m/?s={}&type=1'.format('雅俗共赏')
driver=webdriver.Firefox()
driver.get(url)
get_music_name()
selenium会自动打开火狐浏览器,打开网页找到歌曲“雅俗共赏”。
# 爬取音乐(动态页面)
# 搜索函数
def get_music_name():
# 获取歌曲名称
name=entry.get()
url='https://music.163.com/#/search/m/?s={}&type=1'.format(name)
# 隐藏浏览器
option=webdriver.FirefoxOptions()
option.add_argument('--headless')
driver=webdriver.Firefox(firefox_options=option)
# 搜索歌曲页面
# driver = webdriver.Firefox()
driver.get(url)
# 根据id查询到标签
driver.switch_to.frame('g_iframe')
# 获取歌曲id
res = driver.find_element_by_id('m-search')
music_url = res.find_element_by_xpath('.//div[@class="item f-cb h-flag "]/div[2]//a').get_attribute("href")
print(music_url)
# 提取id
music_id = music_url.split('=')[-1]
# print(music_id)
# 提取歌名
music_name=res.find_element_by_xpath('.//div[@class="item f-cb h-flag "]/div[2]//b').get_attribute("title")
# print(music_name)
# 构造字典保存歌曲信息用于下载
item={}
item['music_id']=music_id
item['music_name']=music_name
# 退出浏览器
driver.quit()
说明:
webdriver.Chrome()为启动谷歌浏览器;webdriver.Firefox()为启动火狐浏览器
在driver中自动集成了一些爬虫的工具,不需要再使用正则表达式或者BeautifulSoup等;driver.switch_to.frame()查询指定id=‘g_iframe’下的标签,如上图黄色标记,通过id=‘m-search’找到下方的节点,免于一层层查找的麻烦,通过xpath语法查找,从‘item f-cb h-flag ’再向下找两层div中找到‘a’标签,从而提取出id;提取歌名也是同样的道理;
-
下载歌曲
def music_load(item):
music_id=item['music_id']
music_name=item['music_name']
# id填充到下载url中
music_download_url='https://music.163.com/song/media/outer/url?id={}.mp3'.format(music_id)
# 创建保存文件夹
os.makedirs('music_netease',exist_ok=True)
path='music_netease\{}.mp3'.format(music_name)
# 显示数据到文本框
text.insert(END,'歌曲:{},正在下载...'.format(music_name))
# 文本滚动
text.see(END)
# 更新
text.update()
# 下载
urlretrieve(music_download_url,path)
# 下载完成,显示完成
text.insert(END,'下载完毕:{},请试听!'.format(music_name))
text.see(END)
text.update()
说明:
将搜索函数查找到的歌曲id接入下载链接;
makedirs中exist_ok参数:如果已存在同名文件夹,不会再创建,也不会报错
使用urlretrieve方法可以根据链接直接将下载文件保存到路径中,不需要再次请求打开文件写入;
-
绑定命令
button_start = Button(window,text='开始下载',font=('楷书',15),command='get_music_name')
button_quit = Button(window,text='退出程序',font=('楷书',15),command='window.quit')
将爬虫下载的函数绑定到按钮上,大功告成!
生成可执行文件
打开Pycharm下方的Terminal终端,输入pyinstaller -F 文件名.py(需要提前安装pyinstaller库,并且在py文件所在目录下执行),即可打包成exe文件。
PS:只支持下载客户端免费下载的音乐,无法下载付费音乐和VIP音乐
感想
学无止境,你有爬虫技术,别人就有防止你爬虫的技术,停滞不前就是退步!
爬虫也是学习不久,可能存在一些问题或者改进优化的地方,还请各位大佬不吝赐教,一起进步,嘻嘻。