Python爬取某音乐网站

本文的文字及图片来源于网络,仅供学习、交流使用,不具有任何商业用途,如有问题请及时联系我们以作处理。

爬取某音乐网站,我们先搜索歌曲,然后随意点进一首歌,然后在新弹出的歌曲页面按F12开始抓包,并刷新页面

 抓到之后可以发现有个tracklink的接口返回的json中有音乐地址,打开该音乐地址就是我们要获取的音乐,所以我们要模拟这个过程,再打开一个其他的音乐进行抓包,可以发现请求参数中不同的只有sign和TSID,timestamp是时间戳,TSID是歌曲的ID,所以只有sign是未知的。

 我们通过观察并点进启动器中的js(没有启动器属性的自己右键名称把启动器勾上),然后在该js中搜索sign,可以发现一个名为createSign的js方法,然后搜索这个方法,发现这个js文件有两个名字相同的方法(两个方法的内容也是一样的),我们在这两个方法里都打上断点进行调试,刷新页面,观察参数e是什么,

可以发现参数e就是键值对形式的TSID和appid(16073360), 然后把这个js方法复制到你的python项目中以便调用(注意那个secret参数也是复制过来的),缺少什么就引用什么。

到这里sign的加密问题已经解决了,接下来我们只需要获取TSID就可以了,再进行搜索歌曲并抓包,

 可以发现一个search接口,里面有我们搜出来的歌曲的TSID,好,如出一辙,也是模拟这个过程,我们知道那个js中的createSign中的参数e是键值对形式的TSID,appid,那现在我们不知道TSID是多少怎么模拟这个参数e呢,答案还是在这个方法中打上断点并刷新页面,观察它的参数e,

 可以发现该参数e变成了appid,pageSize,type,word,那就清楚了,搜索音乐的接口传的参数是这些,音乐地址的参数是TSID和appid,然后我们开始编码。

以下是源码。

from cgitb import reset
import requests
import execjs


#调用js方法
def GetSign(e):
    with open(f'案例\百度音乐.js', 'r', encoding='utf-8') as f:
        jscode = f.read()
    ctx = execjs.compile(jscode).call(
        'createSign', e)  # 加密后的sign以及appid,timestamp
    # print(ctx)
    return ctx


def main():
    searchword = "anime"  # 搜索的字段
    pageno = 1  # 页码
    pagesize = 20  # 每一页的数量
    appid = 16073360 # 固定值
    data = {'word': searchword, 'type': 1, 'pageNo': pageno,
            'pageSize': pagesize, 'appid': appid}
    ctx = GetSign(data)
    url = f"https://music.91q.com/v1/search?sign={ctx['sign']}&word={searchword}&pageNo={pageno}&type=1&pageSize={pagesize}&appid={appid}&timestamp={ctx['timestamp']}"
    res = requests.get(url=url).json()
    for songinfo in res["data"]["typeTrack"]:
        songname = songinfo["title"]
        songer = songinfo["artist"][0]["name"]
        id = songinfo["id"]
        data = {'TSID': id, 'appid': appid}
        ctx = GetSign(data)
        url = f"https://music.91q.com/v1/song/tracklink?sign={ctx['sign']}&appid={appid}&TSID={id}&timestamp={ctx['timestamp']}"
        res = requests.get(url, proxies=proxies).json()
        url = res["data"]["path"]
        song = f"{songname}-{songer}"
        music = requests.get(url=url, proxies=proxies).content
        with open(f'爬取的文件\百度音乐/{song}.mp3', 'wb') as f:
            f.write(music)
        print(song+" __已完成")


if __name__ == "__main__":
    main()

猜你喜欢

转载自blog.csdn.net/qq_51502150/article/details/126654695