目录

LOGO

 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
print("""
          ############
      #####################
    ########   ################
   #########################    
   #########          ==============             .;$$s
    ####################          ..:;$$$$$$$$$$ $$$$$$$:..
     #############            ..;$$$$$$$$          $$$$$$$$$:.         
    #############           .:$$$$$$$$             $$$$$$$$$$$$:. 
      ############       .;$$$$$$$$$$           $$$$$$$$$$$$$$$$$$;.      
       ############    .;$$$$$$$$$$$$    $$$$$$$$$$$$$$$$$$$$$$$$$$$;. 
       ###########    ;$$$$$$$$$$$$$$$$  $$$$$$$$$$$$$$$$$$$$$$$$$$$$;      
     ############    ;$$$$$$$$$$$$$$$$$$  $$$$$$$$$$$$$$$$$$$$$$$$$$$$$;     
    ######################################  $$$$$$$$$$$$$$$$$$$$$$$$$$$$:
      ###########################################################################
         #########################################################################
                  :$$$$$$$$$$$$$$$$$$$$$$$$$$ #################################
                  ;$$$$$$$$$$$$$$$$$$$$$$$$$$$$ $$$$$$$$$$$$$$$$$$$$$$$$$$; 
                   ;$$$$$$$$$$$$$$$$$$$$$$$$$$$$ $$$$$$$$$$$$$$$$$$$$$$$$$;   
                ##################################    $$$$$$$$$$$$$$$$$$$$$$$;
                 ##############################################################
                  ############################################################
                        .;$$$$$$$$$$                 ##################### 
                          .:$$$$$$$$               $$$$$$$$$$$$$.    #######  
                             .;$$$$$$$$        $$$$$$$$$$$$$$;.        ######
                                  ...:;$$$$$$$$$$$$$$$$$$$$$:..           ####
         """)

用到的库

1
2
3
4
5
6
import requests
import json
import urllib
import time
import math
import prettytable as pt

定义参数

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
headers = {
    'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36'}
# 搜索歌曲API链接
url = 'https://c.y.qq.com/soso/fcgi-bin/client_search_cp?n=10'
# 搜索链接存放列表
newurl = ['']
# 歌曲mid存放列表
songmids = []
# 歌曲名存放列表
songnames = []
# 歌手名存放列表
singers = []
# 歌曲时长存放列表
times = []

输出使用指导

1
2
3
4
5
6
7
tb1 = pt.PrettyTable()
tb1.field_names = ["指令","功能"]
tb1.add_row(['        s+歌名        ','                   开始搜索/重新搜索                   '])
tb1.add_row(['p+页码','翻页'])      #根据第一行内容长度拉伸,不设置对齐方式默认居中
tb1.add_row(['d+序号','下载对应序号的歌曲'])
tb1.add_row(['quit',' 退出程序'])
print(tb1)

创建请求函数

 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
def request(newurl):
    # newurl为url加上搜索的歌曲名和翻页的页码组成的新链接
    res1 = requests.get(newurl, headers=headers)
    d1 = json.loads(res1.text.strip('callback()[]'))
    d2 = json.loads(res1.text.strip('callback()'))
    d1 = d1['data']['song']['list']
    # 将获取到的信息循环添加到对应列表
    for i in d1:
        songmids.append(i['songmid'])
        songnames.append(i['songname'].replace('(', '('))
        singers.append(i['singer'][0]['name'])
        times.append(time.strftime("%M:%S", time.gmtime(i['interval'])))
    # 截取搜索结果总数
    totalnum = d2['data']['song']['totalnum']
    # 截取当前搜索页码
    curpage = d2['data']['semantic']['curpage']
    # 每页显示10条结果,除以10得搜索结果页数
    cpnum = int(math.ceil(totalnum / 10))
    # 输出搜索结果表格
    tb2 = pt.PrettyTable()
    tb2.field_names = ["序号", "歌名", "歌手", "时长"]
    for i in range(10):
        tb2.add_row([str(i), songnames[i], singers[i], times[i]])
    tb2.add_row(['OK', '搜索结果总数:%s' % totalnum, '当前页码:%s' % curpage, '共%s页' % cpnum])
    # 全部设置左对齐
    tb2.align["歌名"] = "l"
    tb2.align["歌手"] = "l"
    tb2.align["时长"] = "l"
    print(tb2)

创建功能函数

搜索

1
2
3
def search(songname):
    #将新链接添加到newurl列表中
    newurl[0] = url + '&w=%s' % songname

翻页

1
2
3
def pageturn(page):
    #返回添加页码的搜索链接
    return newurl[0] + '&p=%s' % page

下载

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
def download(num):
    #输出下载信息
    print(str(num) + songnames[num] + ' - ' + singers[num] + '.m4a' + ' Downloading...')
    #构建歌曲下载链接并下载
    try:
        res2 = requests.get(
		'https://u.y.qq.com/cgi-bin/musicu.fcg?&data={"req":{"module":"CDN.SrfCdnDispatchServer","method":"GetCdnDispatch","param":{"guid":"2149464175","calltype":0,"userip":""}},"req_0":{"module":"vkey.GetVkeyServer","method":"CgiGetVkey","param":{"guid":"2149464175","songmid":["%s"],"songtype":[0],"uin":"2062209300","loginflag":1,"platform":"20"}},"comm":{"uin":66,"format":"json","ct":24,"cv":0}}' %
            songmids[num], headers=headers)
        html = res2.text
        keyjs = json.loads(html)
        vkey = keyjs['req_0']['data']['midurlinfo'][0]['purl']
        downloadurl = 'https://ws.stream.qqmusic.qq.com/' + vkey
        urllib.request.urlretrieve(downloadurl, songnames[num] + ' - ' + singers[num] + '.m4a')
        print('Download  Finished')
    except:
        print('Download wrong')

清理

1
2
3
4
5
def clear():
    #清空所有列表
    songmids.clear()
    songnames.clear()
    singers.clear()

调用函数运行程序

 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
def run():
    inport = ''
    while inport != 'quit':
        inport = input('请输入一个指令:')
        if inport != '' and len(inport) >= 2:
            if inport[0] == 's':
                try:
                    clear()
                    search(inport[1:])
                    request(newurl[0])
                    continue
                except:
                    print('歌名输入有误')
                    continue
            if inport[0] == 'p':
                pg = inport[1:]
                if pg.isdigit():
                    try:
                        clear()
                        request(pageturn(pg))
                        continue
                    except:
                        print('请先搜索歌名,然后翻页查找')
                        continue
                else:
                    print('序号输入有误,请重新输入')
                    continue
            if inport[0] == 'd':
                sn = inport[1:]
                if len(sn) < 2 and sn in '0123456789':
                    try:
                        download(int(sn))
                        continue
                    except:
                        print('请先搜索歌曲,然后进行下载')
                        continue
                else:
                    print('序号输入有误,请重新输入')
                    continue
        if inport == 'quit':
            print('退出程序')
            exit()
        else:
            print('输入有误,请重新输入')
            print(tb1)

# 运行脚本
if __name__ == '__main__':
    run()

脚本下载链接

点击下载脚本