本文的文字及圖片來源于網路,僅供學習、交流使用,不具有任何商業用途,著作權歸原作者所有,如有問題請及時聯系我們以作處理,
以下文章來源于Python技術,作者 派森醬
轉載地址
https://blog.csdn.net/fei347795790?t=1
現在的音樂APP有很多,為了不下載很多的APP,所以咱用python做了一個聚合的音樂下載器,現在聚合了咪咕音樂、QQ音樂,下面是效果圖
安裝
需要安裝一個輔助模塊 prettytable,用于美化控制臺的表格輸出
pip install prettytable
提取音樂鏈接
搜索音樂
以下載 QQ 音樂為例,在首頁(https://y.qq.com/) 上的搜索框中搜索 <<厚顏無恥>>, 打開 F12 的控制臺面板,可以找到如下圖的搜索鏈接,這個鏈接回傳的是一個音樂串列的 json 串
def get_request(self, url):
try:
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.102 Safari/537.36'
}
response = requests.get(url, headers = headers)
if response.status_code == 200:
return response
except Exception as e:
print("請求出錯:", e)
return None
def search_music(self, key):
# 20: 查詢 20 條資料,key:關鍵字
url = 'https://c.y.qq.com/soso/fcgi-bin/client_search_cp?p=1&n=%d&w=%s' % (20, key)
resp = self.get_request(url)
resp_json = json.loads(resp.text[9:][:-1])
data_song_list = resp_json['data']['song']['list']
song_list = []
for song in data_song_list:
singers = [s.get("name", "") for s in song.get("singer", "")]
song_list.append({'name': song['songname'], 'songmid': song['songmid'], 'singer': '|'.join(singers)})
return song_list
示例結果:
[{'name': '富士山下', 'songmid': '003dtkNk26WhJD', 'singer': '陳奕迅'}, {'name': '不要說話', 'songmid': '002B2EAA3brD5b', 'singer': '陳奕迅'}, ...., {'name': '最佳損友', 'songmid': '003hFxQh276Cv5', 'singer': '陳奕迅'}]
獲取下載鏈接
把音樂串列頁中的歌曲點擊到播放音樂的頁面,在控制面板找到多個以 m4a 結尾的音樂實際鏈接
它的引數部分有一個 vkey 的引數,把 vkey 當作關鍵字在 Network 面板中搜索,找到一個 musics.fcg 結尾的鏈接,vkey 的資料就在它回傳的 json 串中,另外的 purl 的值就是上面的 m4a 鏈接,最后將 https://ws.stream.qqmusic.qq.com 和 purl 拼湊成音樂鏈接,musics.fcg 鏈接中 guid 引數是一個亂數,songmid 引數是上面單個音樂的 songmid,uin 引數是 QQ 號
def download_url(self, song):
guid = str(random.randrange(1000000000, 10000000000))
purl_url = 'https://u.y.qq.com/cgi-bin/musicu.fcg?' \
'&data=https://www.cnblogs.com/hhh188764/archive/2020/09/28/{"req":{"param":{"guid":" %s"}},' \
'"req_0":{"module":"vkey.GetVkeyServer","method":"CgiGetVkey","param":{"guid":"%s","songmid":["%s"],"uin":"%s"}},"comm":{"uin":%s}}' \
% (guid, guid, song['songmid'], 0, 0)
resp = self.get_request(purl_url)
if resp is None:
return 'N', 'None', '.m4a'
resp_json = json.loads(resp.text)
purl = resp_json['req_0']['data']['midurlinfo'][0]['purl']
# 有些音樂在網站上不能聽
if len(purl) < 1:
msg = 'N'
download_url = 'http://ws.stream.qqmusic.qq.com/' + purl
song_data = self.get_request(download_url)
if song_data:
msg = 'Y'
return msg, download_url, '.m4a'
示例結果:
只有一個域名的地址的下載鏈接表示這個音樂只能在客戶端聽,網頁版聽不了
到這里已經完了 QQ 音樂的搜索、抓取腳本,用同樣的方式抓取咪咕音樂(http://m.music.migu.cn)做成咪咕音樂腳本,咪咕音樂更容易爬取
命令列主界面
主界面的主要功能就是以表格的方式顯示搜索到的音樂和以序號的方式下載音樂
import os
from qqMusic import QQMusic
from miguMusic import MiGuMusic
from prettytable import PrettyTable
class MusicBox(object):
def __init__(self):
pass
def download(self, data, songName, type):
save_path = 'music/' + songName + '.' + type
file = 'music'
if os.path.exists(file):
pass
else:
os.mkdir('music')
try:
print("{}下載中.....".format(songName), end='')
with open(save_path, 'wb') as f:
f.write(data)
print("已下載完成")
except Exception as err:
print("檔案寫入出錯:", err)
return None
def main(self):
print('請輸入需要下載的歌曲或者歌手:')
key = input()
print('正在查詢..\033[32mQQ音樂\033[0m', end='')
qqMusic = QQMusic()
qq_song_list = qqMusic.main(key)
print('...\033[31m咪咕音樂\033[0m')
miguMusic = MiGuMusic()
migu_song_list = miguMusic.main(key)
qq_song_list.extend(migu_song_list)
song_dict = {}
for song in qq_song_list:
key = song['name'] + '\\' + song['singer']
s = song_dict.get(key)
if s:
if s['msg'] != 'Y':
song_dict[key] = song
else:
song_dict[key] = song
i = 0
table = PrettyTable(['序號', '歌手', '下載', '歌名'])
table.border = 0
table.align = 'l'
for song in list(song_dict.values()):
i = i + 1
table.add_row([str(i), song['singer'], song['msg'], song['name']])
print(table)
while 1:
print('\n請輸入需要下載,按 q 退出:')
index = input()
if index == 'q':
return
song = list(song_dict.values())[int(index) - 1]
data = qqMusic.get_request(song['downloadUrl'])
if song['msg'] == 'Y':
self.download(data.content, song['name'], song['type'])
else:
print('該歌曲不允許下載')
if __name__ == '__main__':
musicBox = MusicBox()
musicBox.main()
總結
音樂聚合下載器最重要的部分還是爬蟲抓取各個音樂網站的資料,命令列的方式則省去了畫 GUI 的作業,
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/134889.html
標籤:其他
上一篇:學習第39天
下一篇:Python函式詳解
