前言
那么今天我们就来爬一波网易云个人听歌排行榜吧。让我们愉快地开始吧~
开发工具
Python版本:3.6.4
相关模块:
argparse模块;
DecryptLogin模块;
prettytable模块;
以及一些python自带的模块。
环境搭建
安装Python并添加到环境变量,pip安装需要的相关模块即可。
DecryptLogin安装方式参见(因为经常更新,已经安装过的小伙伴麻烦记得更新一下,否则可能会在新的案例中报错)
原理简介
首先,打开网易云,随便找个用户刷新他的听歌排行榜页面并抓包:
发现只要请求类似这样的链接就可以获得该用户的听歌排行榜了:
https://music.163.com/weapi/v1/play/record?csrf_token=90f3b95109118c7335b896e2c24d7ebd
复制代码
返回的数据是这样的:
现在考虑一下怎么构造这个请求,首先是csrf_token这个东西从哪来,之前的文章其实说过,在用户登录后的cookies里可以直接找到该参数,如下图红框所示(当然如果在非登录状态下也能看到目标用户的听歌排行榜,那么这个csrf_token其实是可有可无的):
接着考虑一下怎么算post参数,因为DecryptLogin库里已经写好了,所以我们这里只考虑怎么得到post数据的原文,查看一下initiator,发现Ajax请求的发起方是某core.js文件:
点进去在对应的位置打个断点(也就是需要用post数据的原文来计算最终的post参数的函数那里,至于怎么找到的,全局搜索encSecKey,然后简单分析一下它的计算流程就可以找到了这个函数啦),然后重新运行一下脚本,我们就可以看到post数据的原文啦:
于是我们就可以愉快地开始写代码啦,核心代码如下:
'''获得某用户的听歌排行榜'''
def getLeaderboard(self, uid):
url = 'https://music.163.com/weapi/v1/play/record?csrf_token=' + self.csrf
data = {
'type': '-1',
'uid': uid,
'limit': '1000',
'offset': '0',
'total': 'true',
'csrf_token': self.csrf
}
res = self.session.post(url, headers=self.headers, data=self.cracker.get(data))
res_json = res.json()
leader_board = {'weekData': [], 'allData': []}
if res_json['code'] == 200:
all_data = res_json.get('allData')
for item in all_data:
songname = item.get('song').get('name')
songid = item.get('song').get('id')
play_count = item.get('playCount')
leader_board['allData'].append([songid, songname, play_count])
week_data = res_json.get('weekData')
for item in week_data:
songname = item.get('song').get('name')
songid = item.get('song').get('id')
play_count = item.get('playCount')
leader_board['weekData'].append([songid, songname, play_count])
else:
raise RuntimeError('Fail to get leaderboard for %s...' % uid)
return leader_board
复制代码
看完篇文章喜欢的朋友点个赞支持一下,关注我每天分享Python模拟登录系列,下篇文章分享拉勾网模拟登录
All done~完整源代码详见个人简介或者私信获取相关文件。。
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END