"""
思路:
1、f12查看歌单列表,查找有价值元素(可以在htmL中获取,但发现在网路中获取更简便)歌名,歌mid
2、通过播放音乐来找到单个歌曲下载规律(可以在htmL中获取,但发现在网路中获取更简便),f12在媒体中发现了播放连接,发现连接是拼接的
3、通过f12查找,发现拼接的元素key在网络文件中可以获取(response)
4、发现请求网络文件的连接是由密钥sign和携带的数据文件data拼接而成
5、密钥通过在网络文件中查找,发现了生成其的js文件,通过debug,发现生成密钥须传入data,data文件中需要歌曲的mid。将js文件复制到本地
"""
打开qq音乐歌单,f12,在网络中XHR(动态资源)找到歌曲的信息
通过播放单曲音乐来找到下载连接
通过查找网络文件找到下载连接中的key值
获取key值的请求中有加密参数sign, 通过ctcl + f 输入sign,可以看到一个js加密文件,以及一个获取sign的方法
直接上代码:
import urllib.request
import urllib.parse # URL只允许一部分ASCII字符,其他字符(如汉字)是不符合标准的,此时就要进行编码。
import json # 1、将字典序列化,2、将代码转换为json格式
import pprint # 美化代码
import execjs # 执行js文件
"""
思路:
1、f12查看歌单列表,查找有价值元素(可以在htmL中获取,但发现在网路中获取更简便)歌名,歌mid
2、通过播放音乐来找到单个歌曲下载规律(可以在htmL中获取,但发现在网路中获取更简便),f12在媒体中发现了播放连接,发现连接是拼接的
3、通过f12查找,发现拼接的元素key在网络文件中可以获取(response)
4、发现请求网络文件的连接是由密钥sign和携带的数据文件data拼接而成
5、密钥通过在网络文件中查找,发现了生成其的js文件,通过debug,发现生成密钥须传入data,data文件中需要歌曲的mid。将js文件复制到本地
"""
"""
要点:
header 中referer有时也是须传入的 不然会报错
request传入data时传入的是bytes 解决:data = urllib.parse.urlencode(data).encode('utf-8')
结果需要json文件 解决:song_list = json.loads(res.read())["cdlist"][0]["songlist"]
请求网址是拼接而成的可以通过get请求,也可以用post请求但是要传递数据
连接里面有字典传入须将其变为字符串(json序列化) 解决:json.dumps(data, separators=(',',':')) # separators=(',',':') 消除空格
URL只允许一部分ASCII字符,其他字符(如汉字)是不符合标准的,此时就要进行编码。 解决:urllib.parse.unquote() 将字符串换为url json序列化也可以解决
函数返回两个值,通过 yield name_list, mid_list # 生成器,可返回两个结果,直接将其转换为列表可获取结果 song_info = list(get_songinfo()) # 将生成器返回的结果转换为列表
"""
"""
根据js文件获取加密sign值
"""
def getSign(data):
#(1)打开并读取js文件(注意编码格式)
with open("爬虫\getsign.js", 'r', encoding='UTF-8') as f:
text = f.read()
#(2)通过execjs库加载并编译js文件
sign = execjs.compile(text).call('getSign',data)
return sign
def get_songinfo():
name_list = [] # 获取歌单中的歌名和mid
mid_list = []
url = "https://c.y.qq.com/qzone/fcg-bin/fcg_ucc_getcdinfo_byids_cp.fcg" # 可以用post方式请求,省略后面的字符串网址
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.105 Safari/537.36 Edg/84.0.522.58",
"referer": "https://y.qq.com/"
}
data = {
"type": "1",
"json": "1",
"utf8": "1",
"onlysong": "0",
"new_format": "1",
"disstid": "7683698159",
"g_tk_new_20200303" : "5381",
"g_tk": "5381",
"loginUin": "2632959523",
"hostUin" : "0",
"format": "json",
"inCharset": "utf8",
"outCharset": "utf-8",
"notice": "0",
"platform": "yqq.json",
"needNewCode": "0",
}
data = urllib.parse.urlencode(data).encode