python+selenium+tkinter打造網易雲音樂下載器

前言

網易雲音樂相信很多小夥伴都用過,是一個非常不錯的音樂播放器。

但是越來越多的歌曲開始加入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,操作更方便哦

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章