python爬取虾米音乐_虾米音乐爬虫

import requests, pprint

from fake_useragent import UserAgent

from hashlib import md5

class XiaMi:

ua = UserAgent()

DOMAIN = "https://www.xiami.com"

# 各个API接口地址

# 每日音乐推荐

APIDailySongs = "/api/recommend/getDailySongs"

# 排行榜音乐

APIBillboardDetail = "/api/billboard/getBillboardDetail"

# 所有排行榜

APIBillboardALL = "/api/billboard/getBillboards"

# 歌曲详情信息

APISongDetails = "/api/song/getPlayInfo"

def __init__(self):

self.session = requests.Session()

self.headers = {

"user-agent": self.ua.random

}

self.session.get(self.DOMAIN)

def _get_api_url(self, api):

return self.DOMAIN + api

# 获取每日推荐的30首歌曲

def get_daily_songs(self):

url = self._get_api_url(self.APIDailySongs)

params = {

"_s": self._get_params__s(self.APIDailySongs)

}

result = self.session.get(url=url, params=params).json()

self._dispose(result)

# 获取虾米音乐的音乐排行榜

def get_billboard_song(self, billboard_id: int = 0):

'''

:param billboard_id: 各类型的排行榜

:return: 排行榜音乐数据

'''

if not hasattr(self, "billboard_dict"):

self._get_billboard_dict_map()

assert hasattr(self, "billboard_dict"), "billboard_dict获取失败"

pprint.pprint(self.billboard_dict)

if billboard_id == 0:

billboard_id = input("输入对应ID,获取排行榜信息")

assert billboard_id in self.billboard_dict, "billboard_id错误"

url = self._get_api_url(self.APIBillboardDetail)

_q = '{\"billboardId\":\"%s\"}' % billboard_id

params = {

"_q": _q,

"_s": self._get_params__s(self.APIBillboardDetail, _q)

}

result = self.session.get(url=url, params=params).json()

self._dispose(result)

# 生成一个排行榜对应的字典映射

def _get_billboard_dict_map(self):

billboard_dict = {}

billboards_info = self.get_billboard_all()

try:

if billboards_info["code"] == "SUCCESS":

xiamiBillboards_list = billboards_info["result"]["data"]["xiamiBillboards"]

for xiamiBillboards in xiamiBillboards_list:

for xiamiBillboard in xiamiBillboards:

id = xiamiBillboard["billboardId"]

name = xiamiBillboard["name"]

billboard_dict[id] = name

self.billboard_dict = billboard_dict

except Exception:

pass

# 获取所有的排行榜信息

def get_billboard_all(self):

url = self._get_api_url(self.APIBillboardALL)

params = {

"_s": self._get_params__s(self.APIBillboardALL)

}

result = self.session.get(url=url, params=params).json()

self._dispose(result)

# 获取歌曲详情信息

def get_song_details(self, *song_ids) -> dict:

'''

:param song_ids: 歌曲的id,可以为多个

:return: 歌曲的详情信息

'''

assert len(song_ids) != 0, "参数不能为空"

for song_id in song_ids:

if not isinstance(song_id, int):

raise Exception("每个参数必须为整型")

url = self._get_api_url(self.APISongDetails)

_q = "{\"songIds\":%s}" % list(song_ids)

params = {

"_q": _q,

"_s": self._get_params__s(self.APISongDetails, _q)

}

result = self.session.get(url=url, params=params).json()

return self._dispose(result)

# 获取歌曲的下载地址

def get_song_download_url(self, *song_ids):

download_url_dict = {}

song_details = self.get_song_details(*song_ids)

songPlayInfos = song_details["result"]["data"]["songPlayInfos"]

for songPlayInfo in songPlayInfos:

song_download_url = songPlayInfo["playInfos"][0]["listenFile"] or songPlayInfo["playInfos"][1]["listenFile"]

song_id = songPlayInfo["songId"]

download_url_dict[song_id] = song_download_url

print("歌曲下载地址为:", download_url_dict)

# 处理爬虫获取到的数据,这里我就输出值

def _dispose(self, data):

pprint.pprint(data)

return data

# 获取加密字符串_s

def _get_params__s(self, api: str, _q: str = "") -> str:

'''

:param api: URL的地址

:param _q: 需要加密的参数

:return: 加密字符串

'''

xm_sg_tk = self._get_xm_sg_tk()

data = xm_sg_tk + "_xmMain_" + api + "_" + _q

return md5(bytes(data, encoding="utf-8")).hexdigest()

# 获取xm_sg_tk的值,用于对数据加密的参数

def _get_xm_sg_tk(self) -> str:

xm_sg_tk = self.session.cookies.get("xm_sg_tk", None)

assert xm_sg_tk is not None, "xm_sg_tk获取失败"

return xm_sg_tk.split("_")[0]

def test(self):

# self.get_daily_songs()

# self._get_xm_sg_tk()

# self.get_billboard_song(332)

# self.get_billboard_all()

# self.get_song_details(1813243760)

# self.get_song_download_url(1813243760)

pass

if __name__ == '__main__':

xm = XiaMi()

xm.test()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值