<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          用 Python 制作音樂聚合下載器

          共 2424字,需瀏覽 5分鐘

           ·

          2020-09-28 08:33

          文 |?某某白米飯

          來源:Python 技術(shù)「ID: pythonall」

          現(xiàn)在的音樂APP有很多,為了不下載很多的APP,所以咱用python做了一個(gè)聚合的音樂下載器,現(xiàn)在聚合了咪咕音樂、QQ音樂,下面是效果圖

          安裝

          需要安裝一個(gè)輔助模塊 prettytable,用于美化控制臺(tái)的表格輸出

          pip?install?prettytable

          提取音樂鏈接

          搜索音樂

          以下載 QQ 音樂為例,在首頁(https://y.qq.com/) 上的搜索框中搜索 <<厚顏無恥>>, 打開 F12 的控制臺(tái)面板,可以找到如下圖的搜索鏈接,這個(gè)鏈接返回的是一個(gè)音樂列表的 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("請(qǐng)求出錯(cuò):",?e)
          ????????
          ????return?None

          def?search_music(self,?key):
          ????# 20:?查詢 20?條數(shù)據(jù),key:關(guān)鍵字
          ????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

          示例結(jié)果:

          [{'name':?'富士山下',?'songmid':?'003dtkNk26WhJD',?'singer':?'陳奕迅'},?{'name':?'不要說話',?'songmid':?'002B2EAA3brD5b',?'singer':?'陳奕迅'},?....,?{'name':?'最佳損友',?'songmid':?'003hFxQh276Cv5',?'singer':?'陳奕迅'}]

          獲取下載鏈接

          把音樂列表頁中的歌曲點(diǎn)擊到播放音樂的頁面,在控制面板找到多個(gè)以 m4a 結(jié)尾的音樂實(shí)際鏈接

          它的參數(shù)部分有一個(gè) vkey 的參數(shù),把 vkey 當(dāng)作關(guān)鍵字在 Network 面板中搜索,找到一個(gè) musics.fcg 結(jié)尾的鏈接,vkey 的數(shù)據(jù)就在它返回的 json 串中,另外的 purl 的值就是上面的 m4a 鏈接,最后將 https://ws.stream.qqmusic.qq.com 和 purl 拼湊成音樂鏈接,musics.fcg 鏈接中 guid 參數(shù)是一個(gè)隨機(jī)數(shù),songmid 參數(shù)是上面單個(gè)音樂的 songmid,uin 參數(shù)是 QQ 號(hào)

          def?download_url(self,?song):
          ????guid?=?str(random.randrange(1000000000,?10000000000))

          ????purl_url?=?'https://u.y.qq.com/cgi-bin/musicu.fcg?'?\
          ????????????????'&data={"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']

          ????#?有些音樂在網(wǎng)站上不能聽
          ????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'

          示例結(jié)果:

          只有一個(gè)域名的地址的下載鏈接表示這個(gè)音樂只能在客戶端聽,網(wǎng)頁版聽不了

          到這里已經(jīng)完了 QQ 音樂的搜索、抓取腳本,用同樣的方式抓取咪咕音樂(http://m.music.migu.cn)做成咪咕音樂腳本,咪咕音樂更容易爬取

          命令行主界面

          主界面的主要功能就是以表格的方式顯示搜索到的音樂和以序號(hào)的方式下載音樂

          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("文件寫入出錯(cuò):",?err)
          ????????????return?None

          ????def?main(self):
          ????????print('請(qǐng)輸入需要下載的歌曲或者歌手:')
          ????????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(['序號(hào)',?'歌手',?'下載',?'歌名'])
          ????????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ǐng)輸入需要下載,按 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()

          總結(jié)

          音樂聚合下載器最重要的部分還是爬蟲抓取各個(gè)音樂網(wǎng)站的數(shù)據(jù),命令行的方式則省去了畫 GUI 的工作。

          PS公號(hào)內(nèi)回復(fù)「Python」即可進(jìn)入Python 新手學(xué)習(xí)交流群,一起?100 天計(jì)劃!


          老規(guī)矩,兄弟們還記得么,右下角的 “在看” 點(diǎn)一下,如果感覺文章內(nèi)容不錯(cuò)的話,記得分享朋友圈讓更多的人知道!

          代碼獲取方式

          識(shí)別文末二維碼,回復(fù):200927


          瀏覽 61
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  成人午夜免费视频 | 无不卡无码高清视频在线观看 | www.大鸡巴 | 综合一区二区三区 | 国产avtt |