1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180
| from curses.ascii import isdigit from sre_compile import isstring import requests, json, sys, time, os from you_get import common from bs4 import BeautifulSoup
headers = {'User-Agent': "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; .NET4.0C; .NET4.0E; rv:11.0) like Gecko"}
class TemplateError(Exception): def __init__(self, err): print("程序出现了错误: "+err) Exception().__init__(self, err) class FanMangError(TemplateError): def __init__(self, code): err = '网易云音乐出现了系统繁忙,请在几分钟之后重启程序。错误码: %s' % code super().__init__(self, err)
class NotExist404(TemplateError): def __init__(self): err = '您输入的ID指向不存在的音乐。' super().__init__(self, err)
class VIPMusicError(TemplateError): def __init__(self): err = '请使用网易云音乐APP下载VIP音乐。' super().__init__(err)
class IDError(TemplateError): def __init__(self): err = '错误的ID' super().__init__(self, err)
def IDTester(ID, ignorance=True): try: if isdigit(ID) == False and ignorance == False: print(f'ID:{ID}出现错误,请检查是否正确。') logWriter('出现了错误ID: '+ID+",程序自动退出。", error=True) sys.exit(0) if isdigit(ID) == False and ignorance == True: logWriter('出现了错误ID: '+ID+",程序未退出",error=True) ID = str(ID) raise IDError if isstring(ID) == False: ID = str(ID) except: print(f'ID:{ID}出现错误,请检查是否正确。') return ID
c = os.path.abspath('.') def wyydownloader(ID, ignorance=True, where='.'): ''' 利用官方API实现。 ID是一个字符串,是网易云音乐的歌曲ID, ignorance是一个是否被错误打断的boolean,若为True则忽视VIP歌曲无法下载错误并给予反馈。 ''' if os.getcwd() != c+where: os.chdir(where) ID = IDTester(ID) data = requests.get('http://music.163.com/api/song/detail/?id='+ID+'&ids=%5B'+ID+'%5D', headers=headers) if data.content == r'{"songs":[],"equalizers":{},"code":200}': raise NotExist404 n = json.loads(data.content) state = n['songs'][0]['fee'] if state == 1 and ignorance == False: raise VIPMusicError if state == 1 and ignorance == True: return 0 name = n['songs'][0]['name'] creator = n['songs'][0]['artists'][0]['name'] chunk_size = 1024 response = requests.get('http://music.163.com/song/media/outer/url?id=%s.mp3' % ID, headers=headers) file_size = response.headers.get('Content-Length') if file_size is not None: file_size = int(file_size) with open(f'{name} - {creator}.mp3', mode='wb') as f: for chunk in response.iter_content(chunk_size=chunk_size): f.write(chunk) logWriter(f'ID为{ID}的歌曲下载成功。',error=False)
def searcher(name): f, c, d, k, _ = [], [], [], [], [] data = requests.get(r'http://music.163.com/api/search/get/web?csrf_token=hlpretag=&hlposttag=&s={'+name+r'}&type=1&offset=0&total=true&limit=20',headers=headers) n = json.loads(data.content)['result']['songs'][0:9] for x in range(len(n)): f.append(n[x]['name']) c.append(n[x]['artists'][0]['name']) d.append(n[x]['id']) for y in range(len(n)): k.append([f[y],c[y],str(d[y])]) for z in range(len(n)): _.append(('['+str(z)+']')+" | ".join(k[z])) for __ in range(len(n)): print(_[__]) a = input('请输入你选择下载的歌曲: ') wyydownloader(str(d[int(a)]))
def album_web(ID): ID = IDTester(ID) url = "https://music.163.com/album?id=" + ID response = requests.get(url=url, headers=headers) html=response.content.decode(encoding="utf-8") soup = BeautifulSoup(html, 'lxml') results = soup.find('ul',{'class':'f-hide'}) results=results.find_all('a') download = wyydownloader(results[0]['href'].split("=")[1],where='./'+ID) for music in results: try: download = wyydownloader(music['href'].split("=")[1]) if download == 0: print('因VIP歌曲的版权原因,该歌曲无法下载。') logWriter('因VIP歌曲的原因无法下载ID为:{ID}的歌曲',error=True) except: print(f'第 {results.index(music)} 首歌曲的下载出现了问题') continue
def playlist_web(ID): ID = IDTester(ID) url = "https://music.163.com/playlist?id=" + ID response = requests.get(url=url, headers=headers) html=response.content.decode(encoding="utf-8") soup = BeautifulSoup(html, 'lxml') results = soup.find('ul',{'class':'f-hide'}) results=results.find_all('a') if os.path.exists(f'./{ID}') == False: os.makedirs(f'./{ID}') for music in results: try: download = wyydownloader(music['href'].split("=")[1],where=f'./{ID}') if download == 0: print('因VIP歌曲的版权原因,该歌曲无法下载。') logWriter('因VIP歌曲的原因无法下载ID为:{ID}的歌曲',error=True) except Exception as e: print(f'第 {results.index(music)} 首歌曲的下载出现了问题') print(e) continue
def playlist_full(ID): ID = IDTester(ID) url = 'https://music.163.com/api/playlist/detail?id=' + ID response = requests.get(url=url, headers=headers) results = json.loads(response.content) if results['code'] == -447: raise FanMangError(results['code']) print(results)
def lyrics(ID): ID = IDTester(ID) try: url = 'http://music.163.com/api/song/media?id=' + ID data = json.loads(requests.get(url=url,headers=headers).content) except: print('您输入的ID指向不存在的音乐。') if 'lyric' in data: with open(ID+'.lrc', 'w') as f: f.write(data['lyric'])
def logWriter(msg,error=True): if error == True: state = 'ERROR' else: state = 'INFO' with open('日志.log','a') as f: f.write(f'[{time.localtime(time.time())}][{state}]:'+msg)
if __name__ == '__main__': playlist_web('7266482854')
|