【Python爬虫】爬取网易云音乐,打造音乐下载器

2020-11-17 10:10发布

在前一篇文章,正好总结过了Tkinter以及canvas画布的使用,学以致用,用Tkinter来创建一个窗口,在此基础上实现音乐的下载逻辑,并在最后打包成exe文件。

 最近刚好学了Tkinter和Canvas画布,顺便总结了一下,想着那它来做点什么练练手,我平常挺喜欢听音乐,特别是在大型评论APP平台——网易云音乐(滑稽),歌不仅推荐的好,而且评论“个个说话又好听”。所以想着自己做一个音乐下载器,试一试。结果感觉还可以,起码做出来了,就是界面糙了点,功能简陋点,除了能跑,也就没啥优点了。

废话不多说,上一波效果图。

 先把源码分享出来吧,放在了我的giteeCSDN我的下载中,需要的可自取。下面我分享一下我的代码思路。

搭建窗口

搭建窗口就像画画一样,你需要哪些,可以使用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音乐


 感想

学无止境,你有爬虫技术,别人就有防止你爬虫的技术,停滞不前就是退步!

爬虫也是学习不久,可能存在一些问题或者改进优化的地方,还请各位大佬不吝赐教,一起进步,嘻嘻。


作者:ZoomToday

链接:https://blog.csdn.net/qq_36477513/article/details/104823247

来源:CSDN
著作权归作者所有,转载请联系作者获得授权,切勿私自转载。