当前位置:   article > 正文

【Python3】分析某音乐页面并使用tkinter构建简易GUI_encode_album_audio_id

encode_album_audio_id

Python 分析某音乐页面并使用tkinter构建简易GUI

本人python初学者,记录自己的一次学习过程,仅供参考。欢迎各位前辈指点。

分析页面

本次要分析的页面主要是酷狗音乐搜索界面

思路如下:

  1. 在上图所示页面点击播放一首音乐后,F12进入开发者模式,找到含有音乐的play_url的请求网址,该url就是音乐播放的url。
  2. 在对请求网址进行删减后,注意到encode_album_audio_id(红框内)的参数,似乎是代表着音乐的id。
  3. 所以如果有了每首歌曲的encode_album_audio_id,也就获得了这首歌曲的play_url
  4. 返回到搜索界面,进入开发者模式,并Ctrl+F搜索红框内encode_album_audio_id,发现了一个list,里面包含了搜索界面的音乐信息;
  5. 我们在对应的音乐里面,发现了和encode_album_audio_id相同的值——EMixSongID
    所以现在的任务也就变成了提取每首音乐的EMixSongID,也就是得到了encode_album_audio_id,同时就得到了play_url
  6. 观察请求页面的参数
    尝试了不同几个页面的参数后,发现只有clienttimesignature是变化的。(可能还有关键字keyword)
    其中clientime为当前时间戳,pyhon time库处理简单。
    关于signature的处理可自行查找。
  7. 接下来的任务就是对url中的json格式进行处理,提取EMixSongID
  8. 将得到得到不同歌曲的不同的EMixSongID进行url拼接,得到含有该首歌曲play_url的url,再次对该页面进行json处理,得到play_url,完成。
def get_url():
	k = time.time()
	k = int(round(k * 1000))
	text = input("请输入搜索关键字")
	info = [
	    "NVPh5oo715z5DIWAeQlhMDsWXXQV4hwt",
	    "appid=1014",
	    "bitrate=0",
	    "callback=callback123",
	    "clienttime={}".format(k),
	    "clientver=1000",
	    "dfid=34d3K63Qc3AA3wvcEp1te6TT",
	    "filter=10",
	    "inputtype=0",
	    "iscorrection=1",
	    "isfuzzy=0",
	    "keyword={}".format(text),
	    "mid=41d5a0c36112c5cb310d75b0ab73ac0f",
	    "page=1",
	    "pagesize=30",
	    "platform=WebFilter",
	    "privilege_filter=0",
	    "srcappid=2919",
	    "token=",
	    "userid=0",
	    "uuid=41d5a0c36112c5cb310d75b0ab73ac0f",
	    "NVPh5oo715z5DIWAeQlhMDsWXXQV4hwt"]
	# 创建md5对象
	new_md5 = md5()
	info = ''.join(info)
	# 更新哈希对象
	new_md5.update(info.encode(encoding='utf-8'))
	# 加密
	result = new_md5.hexdigest()
	music_info_url = 'https://complexsearch.kugou.com/v2/search/song?callback=callback123&srcappid=2919&clientver=1000&clienttime={}&' \
	                 'mid=41d5a0c36112c5cb310d75b0ab73ac0f&uuid=41d5a0c36112c5cb310d75b0ab73ac0f&dfid=34d3K63Qc3AA3wvcEp1te6TT&' \
	                 'keyword={}&page=1&pagesize=30&bitrate=0&isfuzzy=0&inputtype=0&platform=WebFilter&userid=0&iscorrection=1&' \
	                 'privilege_filter=0&filter=10&token=&appid=1014&signature={}'.format(k, text, result)
	
	headers = {
	    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36',
	    'Cookie': '填入你自己的Cookie'
	}
	# 请求搜索界面的URL
	minfo_get = requests.get(music_info_url, headers=headers).text
	# 获得该页面的json格式并处理
	minfo_get = minfo_get[12:-2]
	minfo = json.loads(minfo_get)['data']['lists']
	
	num = json.loads(minfo_get)['data']['pagesize']
	for j in range(0, num - 1):
	    song_name = minfo[j]['SongName']
	    singer_name = minfo[j]['SingerName']
	    # dfid这个参数部分歌曲不能缺少,缺少则会出现出现无法正常获得url的情况。
	    # 但大多数歌曲都可以没有该参数。
	    # 如果有人知道原因的话,希望解答一下。感恩!
	    music_url = 'https://wwwapi.kugou.com/yy/index.php?r=play/getdata&dfid=34d3K63Qc3AA3wvcEp1te6TT&encode_album_audio_id={}'.format(minfo[j]['EMixSongID'])
	    print(music_url)
	    get_play_url = requests.get(music_url, headers=headers).text
	    play_url = json.loads(get_play_url)['data']['play_url']
	    print(play_url)
  • 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

保存

该部分的代码非常简单。
代码如下:

		# 选择位置
	    download_place = "pachong_music"
	    try:
	        with open('{}/{}---{}.mp3'.format(download_place, song_name, singer_name), 'wb') as f:
	            f.write(requests.get(play_url).content)
	            print("{}--{}保存成功".format(song_name, singer_name))
	    # 若无该歌曲资源
	    except requests.exceptions.MissingSchema as e:
	        print("{}--{}暂时不能播放".format(song_name, singer_name))
	    except KeyError as e:
	        print("{}--{}保存失败".format(song_name, singer_name))
	    f.close()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

简单GUI的制作

本文界面制作使用的是tkinter库。由于python水平还比较差,所以功能非常简单。
只有搜索并显示音乐信息。
浏览本地文件夹,选择位置。
希望以后学习,能够完善更多功能。
在这里插入图片描述

点击按钮后,改变相应的变量值选择方法是使用全局变量。下面直接放代码吧。
滚动窗口使用的是tkinter中的scrolledtext
浏览使用的是tkinter中的filedialog

全部代码

import json
import time
from hashlib import md5
import requests
import tkinter as tk
from tkinter import scrolledtext
from tkinter import filedialog


def get_url():
    global music_info_url
    text = key_word.get()
    # TODO:自定义关键词搜索页面的URL
    # js逆向部分参考:https://www.cnblogs.com/wxd501/p/17071045.html
    k = time.time()
    k = int(round(k * 1000))
    info = [
        "NVPh5oo715z5DIWAeQlhMDsWXXQV4hwt",
        "appid=1014",
        "bitrate=0",
        "callback=callback123",
        "clienttime={}".format(k),
        "clientver=1000",
        "dfid=34d3K63Qc3AA3wvcEp1te6TT",
        "filter=10",
        "inputtype=0",
        "iscorrection=1",
        "isfuzzy=0",
        "keyword={}".format(text),
        "mid=41d5a0c36112c5cb310d75b0ab73ac0f",
        "page=1",
        "pagesize=30",
        "platform=WebFilter",
        "privilege_filter=0",
        "srcappid=2919",
        "token=",
        "userid=0",
        "uuid=41d5a0c36112c5cb310d75b0ab73ac0f",
        "NVPh5oo715z5DIWAeQlhMDsWXXQV4hwt"]
    # 创建md5对象
    new_md5 = md5()
    info = ''.join(info)
    # 更新哈希对象
    new_md5.update(info.encode(encoding='utf-8'))
    # 加密
    result = new_md5.hexdigest()
    music_info_url = 'https://complexsearch.kugou.com/v2/search/song?callback=callback123&srcappid=2919&clientver=1000&clienttime={}&' \
                     'mid=41d5a0c36112c5cb310d75b0ab73ac0f&uuid=41d5a0c36112c5cb310d75b0ab73ac0f&dfid=34d3K63Qc3AA3wvcEp1te6TT&' \
                     'keyword={}&page=1&pagesize=30&bitrate=0&isfuzzy=0&inputtype=0&platform=WebFilter&userid=0&iscorrection=1&' \
                     'privilege_filter=0&filter=10&token=&appid=1014&signature={}'.format(k, text, result)
    # con_info.insert("end", music_info_url)
    # con_info.insert("end", '\n')
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36',
        'Cookie': '****'
    }
    minfo_get = requests.get(music_info_url, headers=headers).text
    minfo_get = minfo_get[12:-2]
    minfo = json.loads(minfo_get)['data']['lists']

    # for i, k in enumerate(minfo):
    #     print(i, k['SingerName'], k['EMixSongID'])
    # num为页码包含歌曲数量
    num = json.loads(minfo_get)['data']['pagesize']
    con_info.insert("end", '搜索到的歌曲如下:\n')
    for j in range(0, num - 1):
        song_name = minfo[j]['SongName']
        singer_name = minfo[j]['SingerName']
        music_url = 'https://wwwapi.kugou.com/yy/index.php?r=play/getdata&dfid=34d3K63Qc3AA3wvcEp1te6TT&encode_album_audio_id={}'.format(minfo[j]['EMixSongID'])
        get_play_url = requests.get(music_url, headers=headers).text
        json.loads(get_play_url)['data']['play_url']
        con_info.insert("end", "{}--{}".format(song_name, singer_name))
        con_info.insert("end", '\n')


# TODO:浏览文件夹,选择本地位置
def browse():
    global download_place
    download_place = filedialog.askdirectory()
    con_info.insert("end", "即将保存的路径为{}".format(download_place))
    con_info.insert("end", '\n')


# TODO:获取并写入文件
def download_music():
    global music_info_url
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36',
        'Cookie': 'kg_mid=41d5a0c36112c5cb310d75b0ab73ac0f; kg_dfid=34d3K63Qc3AA3wvcEp1te6TT; kg_dfid_collect=d41d8cd98f00b204e9800998ecf8427e; Hm_lvt_aedee6983d4cfc62f509129360d6bb3d=1677400096; Hm_lpvt_aedee6983d4cfc62f509129360d6bb3d=1677411756'
    }
    minfo_get = requests.get(music_info_url, headers=headers).text
    minfo_get = minfo_get[12:-2]
    minfo = json.loads(minfo_get)['data']['lists']

    # num为页码包含歌曲数量
    num = json.loads(minfo_get)['data']['pagesize']

    for j in range(0, num - 1):
        song_name = minfo[j]['SongName']
        singer_name = minfo[j]['SingerName']
        music_url = 'https://wwwapi.kugou.com/yy/index.php?r=play/getdata&encode_album_audio_id={}'.format(
            minfo[j]['EMixSongID'])

        get_play_url = requests.get(music_url, headers=headers).text
        play_url = json.loads(get_play_url)['data']['play_url']

        try:
            with open('{}/{}---{}.mp3'.format(download_place, song_name, singer_name), 'wb') as f:
                f.write(requests.get(play_url).content)
        except requests.exceptions.MissingSchema as e:
            con_info.insert("未获得歌曲{}--{}资源".format(song_name, singer_name))
        except KeyError as e:
            con_info.insert("{}--{}保存失败".format(song_name, singer_name))
        f.close()
        con_info.insert("end", "{}--{}保存成功".format(song_name, singer_name))
        con_info.insert("end", '\n')


if __name__ == '__main__':
    music_info_url = ""
    download_place = ""
    # TODO:UI界面
    root = tk.Tk()
    root.title("music")
    root.geometry('1024x512')
    # 添加搜索关键词框
    key_word = tk.Entry(root)
    key_word.pack()
    # 点击搜索button执行get_url函数,获得连接
    find_button = tk.Button(root, text="搜索", command=get_url)
    find_button.pack()
    # 点击浏览button执行browse函数,选择保存文件存储位置
    browse_button = tk.Button(root, text="浏览", command=browse)
    browse_button.pack()
    # 点击保存button执行download_music函数,保存歌曲
    down_button = tk.Button(root, text="保存", command=download_music)
    down_button.pack()
    # 设置一个输出控制台信息的滚动文本框
    frame2 = tk.LabelFrame(root, text="控制台信息")
    frame2.pack()
    con_info = scrolledtext.ScrolledText(frame2)
    con_info.pack()
    root.mainloop()
  • 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
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/你好赵伟/article/detail/112133
推荐阅读
相关标签
  

闽ICP备14008679号