Python音樂下載器(for QQ music)
阿新 • • 發佈:2018-12-10
之前學習Python時,在GitHub上發現這個很有意思的下載器(雖然介面很醜陋hhhh)...
就是現在還不會爬蟲,自己不會寫(菜哭)
介面是這樣的:
這是程式碼--
# -*- coding: utf-8 -*- import requests import os class MusicDownloader(): ''' QQ音樂下載器 ''' def search(self, song_name): '''搜尋音樂''' headers = {'referer':'http://y.qq.com/portal/search.html', 'user-agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.84 Safari/537.36' } query_parameters = {'ct':'24', 'qqmusic_ver':'1298', 'new_json':'1', 'remoteplace':'txt.yqq.center', 'searchid':'48987344780034770', 't':'0', 'aggr':'1', 'cr':'1', 'catZhida':'1', 'lossless':'0', 'flag_qc':'0', 'p':'1', #分頁 'n':'20', #顯示的結果數量 'w':str(song_name), #必填搜尋歌名 'g_tk':'5381', 'jsonpCallback':'MusicJsonCallback8319472269210575', 'loginUin':'0', 'hostUin':'0', 'format':'json', #json或者jsonp 'inCharset':'utf8', 'outCharset':'utf-8', 'notice':'0', 'platform':'yqq', 'needNewCode':'0' } search_url = 'http://c.y.qq.com/soso/fcgi-bin/client_search_cp' req = requests.get(url=search_url, params=query_parameters, headers=headers) req.raise_for_status() req_json = req.json() song_list = list(req_json.get('data').get('song').get('list')) result_list = [] for song in song_list: result = {} result['sid'] = song.get('id') result['mid'] = song.get('mid') result['media_mid'] = song.get('file').get('media_mid') result['song_title'] = song.get('title') #歌名 result['album_title'] = song.get('album').get('title') #專輯名稱 result['singer_name'] = song.get('singer')[0].get('name') #歌手 result['interval'] = song.get('interval') #時長 result_list.append(result) self.print_song_list(result_list) req.close() return result_list def get_song_url(self, song): '''獲取歌曲''' headers = {'referer':'http://y.qq.com/portal/search.html', 'user-agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.84 Safari/537.36' } query_parameters = {'g_tk':'5381', # 'jsonpCallback':'MusicJsonCallback8064462801977872', 'loginUin':'0', 'hostUin':'0', 'format':'json', 'inCharset':'utf8', 'outCharset':'utf-8', 'notice':'0', 'platform':'yqq', 'needNewCode':'0', 'cid':'205361747', # 'callback':'MusicJsonCallback8064462801977872', #註釋可以關閉jsonp 'uin':'0', 'songmid':str(song.get('mid')), 'filename':'C400'+str(song.get('media_mid'))+'.m4a', 'guid':'6179861260' } song_url = 'http://c.y.qq.com/base/fcgi-bin/fcg_music_express_mobile3.fcg' req = requests.get(url=song_url, params=query_parameters, headers=headers) req.raise_for_status() req_json = req.json() item = req_json.get('data').get('items')[0] req.close() return item def download(self, item, song): ''' 下載歌曲 ''' root = os.path.abspath('.') save_dir = os.path.join(root,'python下載音樂') if not os.path.exists(save_dir): os.mkdir(save_dir) headers = {'referer':'http://y.qq.com/portal/search.html', 'user-agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.84 Safari/537.36' } query_parameters = {'guid':'6179861260', 'vkey':item.get('vkey'), 'uin':'', 'fromtag':'999' } download_url = 'http://dl.stream.qqmusic.qq.com/'+item.get('filename') with requests.get(url=download_url, params=query_parameters, headers=headers, stream=True) as req: req.raise_for_status() chunk_size = 1024 count = 0 total_size = int(req.headers['content-length']) print('>>>歌曲:{} | 歌手:{}\t開始下載↓'.format(song.get('song_title'),song.get('singer_name'))) with open(os.path.join(save_dir, song.get('song_title')+'.m4a'), 'wb') as music_file: for music in req.iter_content(chunk_size=chunk_size): music_file.write(music) count = count + 1 self.schedule(count, chunk_size, total_size) music_file.close() req.close() def schedule(self, block_num, block_size, total_size): ''' 下載進度 :param block_num: :param block_size: :param total_size: :return: ''' per = 100.0 * block_num * block_size / total_size end_str = "\r" if per > 100: per = 100 end_str = '\n' print('下載進度:%s%d%%'%('■'*int(per/2),per), end=end_str) def print_song_list(self, song_list): ''' 格式輸出歌曲列表 :param song_list: :return: ''' print('\n編號\t|歌曲\t|歌手\t|時長\t|專輯') print('----------------------------------') for key, song in enumerate(song_list): mm = int(song.get('interval')) // 60 mm = str(mm) if mm >= 10 else '0'+str(mm) ss = int(song.get('interval')) % 60 ss = str(ss) if ss >= 10 else '0'+str(ss) print('{}\t|{}\t|{}\t|{}\t|{}\t'.format( key, song.get('song_title'), song.get('singer_name'), mm+':'+ss, song.get('album_title') )) print('----------------------------------\n') def start_download(self): '''開始下載''' print('■■■■■■■■■■■■■■■■■■■■') print('\n QQ音樂下載器\n') print('■■■■■■■■■■■■■■■■■■■■') host = 'http://y.qq.com/' headers = {'user-agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.84 Safari/537.36'} try: req = requests.get(url=host,headers=headers) req.raise_for_status() req.close() except: print('無法訪問y.qq.com,請檢測是否聯網或網址是否有效!!!') return None while True: try: song_name = input('\n> 搜尋(請輸入歌名):') search_result = self.search(song_name) except Exception as e: print(e) print('歌曲搜尋失敗!!!請結束下載') try: num = int(input('> 請輸入歌曲編號:')) song_result = self.get_song_url(search_result[num]) except Exception as e: print(e) print('歌曲解析失敗!!!請結束下載') try: self.download(song_result, search_result[num]) except Exception as e: print(e) print('歌曲下載失敗!!!請結束下載') is_continue = input('是否繼續下載(y/n):') if is_continue.lower() == 'n': break; print('>>>退出下載') if __name__=='__main__': md = MusicDownloader() md.start_download()