我们之前已经学习了selenium的简单实用,现在就来实战下,我们通过selenium获取歌曲的id,然后通过网易云音乐的外链地址来下载音乐,做一个音乐下载器(此项目仅供教学使用),下面我们先来看一下效果:
老规矩,我们先来分析下这个音乐下载器的构成:
首先我们先把软件的界面先做出来:
from tkinter import *
window = Tk()
window.geometry('300x500')
window.title('音乐下载器')
Label(window,text='请输入你想搜索的音乐:',font=('楷体',12)).place(x=10,y=10)
# 输入框
key_word = Entry(window,width=25,font=('楷体',16))
key_word.place(x=10,y=30)
# 搜索按钮
def search():
pass
Button(window,text='搜索',width=5,height=1,font=('楷体',16),command=search).place(x=10,y=70)
# 下载按钮
def download():
pass
Button(window,text='下载',width=5,height=1,font=('楷体',16),command=download).place(x=115,y=70)
# 退出按钮
Button(window,text='退出',width=5,height=1,font=('楷体',16),command=quit).place(x=222,y=70)
# 显示搜索内容的列表框
show = Listbox(window,width=25,height=16,font=('楷体',16))
show.place(x=10,y=120)
window.mainloop()
接下来我们就要实现功能了,我们一起来分析一下网页:
好了,现在怎么抓取数据我们也知道了,接下来我们就敲代码实现数据提取的功能:
from selenium import webdriver # 导入库
def get_music_info(key_word): # 我们将获取歌曲的名字、id和歌手
chrome_options = webdriver.ChromeOptions() # 接下来三行是定义浏览器的设置,实现无界面浏览器
chrome_options.add_argument('--headless') # 因为搜索操作是后台操作,省去界面效率将更高
chrome_options.add_argument('--disable-gpu')
driver = webdriver.Chrome(chrome_options=chrome_options) # 创建浏览器对象
url = 'https://music.163.com/#/search/m/?s={}'.format(key_word) # 合成搜索地址
driver.get(url) # 发出访问请求
driver.switch_to.frame('g_iframe') # 获取frame框架内容
# 用xpath的方式获取所有歌曲的全部信息
data_all = driver.find_elements_by_xpath('.//div[@class="item f-cb h-flag "]')
data_all += driver.find_elements_by_xpath('.//div[@class="item f-cb h-flag even "]')
id_ = [] # 保存歌曲的id
name = [] # 保存歌曲的名字
author = [] # 保存歌手的名字
for data in data_all: # 遍历所有歌曲的信息
# 因为我们只需要id就好,所以这里需要进一步字符串切割
id_.append(data.find_element_by_xpath('.//div[@class="td w0"]//a').get_attribute('href').split('=')[1])
# 提取歌曲名称
name.append(data.find_element_by_xpath('.//div[@class="td w0"]//b').get_attribute('title'))
# 提取歌手名称
author.append(data.find_element_by_xpath('.//div[@class="td w1"]//a').text)
return list(zip(name,author,id_)) # 将数据打包
print(get_music_info('沙漠骆驼')) # 这里只做测试用
# 输出结果:
# [('沙漠骆驼', '展展与罗罗', '486814412'), ('沙漠骆驼 (伴奏)', '展展与罗罗', '1320097149'), ('沙漠骆驼(女生版)(Cover:展展与罗罗)', '澪恩Seiwen', '1317952370'), ('沙漠骆驼', '李传胜', '1336778074'), ('沙漠骆驼(女声版)(Cover:展展与罗罗)', '花僮', ……
这边我直接写了一个方法,后面我们直接调用就好,后期可以把这个整成类,搜索和下载做在一块;
我们来看一下搜索按钮对应的代码该怎么写:
info = [] # 存储返回的搜索结果
def search():
global info # 导入全局变量
key = key_word.get() # 获取输入框的内容
info = get_music_info(key) # 调用方法,对歌曲信息进行搜索
for i in range(show.size()): # 清除列表内容
show.delete(0)
for data in info: # 将歌曲信息显示在列表上面
show.insert('end', '{}({})'.format(data[0], data[1])) # 直接显示歌名和歌手就好
Button(window,text='搜索',width=5,height=1,font=('楷体',16),command=search).place(x=10,y=70)
最后就是对下载的实现了,我们在上面已经获取了歌曲的id,我们可以通过外链地址下载音乐(至于什么是外链,自行百度):
def download():
global info # 导入全局变量
index = show.curselection()[0] # 获取列表中选中的index
tmp = info[index] # 将歌曲的信息提取出来
url = 'https://link.hhtjim.com/163/{}.mp3'.format(tmp[2]) # 合成下载链接
data = requests.get(url).content # 获取歌曲的二进制数据
with open('{}({}).mp3'.format(tmp[0],tmp[1]),'wb') as f: # 保存歌曲
f.write(data)
Button(window,text='下载',width=5,height=1,font=('楷体',16),command=download).place(x=115,y=70)
到这里,我们的音乐下载器就做完了,下面附上源码:
from get_music_info import * # 这个是搜索歌曲信息的方法所在的文件
from tkinter import *
import requests
window = Tk()
window.geometry('300x500')
window.title('音乐下载器')
Label(window,text='请输入你想搜索的音乐:',font=('楷体',12)).place(x=10,y=10)
key_word = Entry(window,width=25,font=('楷体',16))
key_word.place(x=10,y=30)
info = []
def search():
global info
key = key_word.get()
info = get_music_info(key)
for i in range(show.size()):
show.delete(0)
for data in info:
show.insert('end', '{}({})'.format(data[0], data[1]))
Button(window,text='搜索',width=5,height=1,font=('楷体',16),command=search).place(x=10,y=70)
def download():
global info
index = show.curselection()[0]
tmp = info[index]
url = 'https://link.hhtjim.com/163/{}.mp3'.format(tmp[2])
data = requests.get(url).content
with open('{}({}).mp3'.format(tmp[0],tmp[1]),'wb') as f:
f.write(data)
Button(window,text='下载',width=5,height=1,font=('楷体',16),command=download).place(x=115,y=70)
Button(window,text='退出',width=5,height=1,font=('楷体',16),command=quit).place(x=222,y=70)
show = Listbox(window,width=25,height=16,font=('楷体',16))
show.place(x=10,y=120)
window.mainloop()