我们分析了Yandex.Music中的收听历史

近一年来,我一直在使用Yandex音乐服务,一切都适合我。 但是此服务中有一个有趣的页面-历史记录。 它按时间顺序存储已收听的所有曲目。 当然,我想下载它并分析我一直听到的声音。



第一次尝试


开始处理此页面时,我立即遇到了问题。 该服务不会一次下载所有曲目,而只会在您滚动时下载。 我不想下载嗅探器并了解流量,并且那时我还没有技巧。 因此,我决定通过使用硒模拟浏览器来简化操作。


该脚本已编写。 但是他工作很不稳定而且很长时间。 但是他确实设法载入了故事。 经过简单分析,我保留了脚本的任何修改,直到一段时间后,我再次不想下载该故事。 希望达到最好,我推出了它。 而且,当然,他犯了一个错误。 然后我意识到是时候该做所有的事情了。


工作选项


为了进行流量分析,我自己选择了Fiddler,因为它与httpshark不同,因为它具有更强大的HTTP流量界面。 运行嗅探器,我希望看到带有令牌的api请求。 但是没有 我们的目标是在music.yandex.ru/handlers/library.jsx 。 对此的要求需要站点上的完全授权。 我们将从她开始。


登入


这里没什么复杂的。 我们转到passport.yandex.ru/auth ,找到请求的参数并提出两个授权请求。


 auth_page = self.get('/auth').text csrf_token, process_uuid = self.find_auth_data(auth_page) auth_login = self.post( '/registration-validations/auth/multi_step/start', data={'csrf_token': csrf_token, 'process_uuid': process_uuid, 'login': self.login} ).json() auth_password = self.post( '/registration-validations/auth/multi_step/commit_password', data={'csrf_token': csrf_token, 'track_id': auth_login['track_id'], 'password': self.password} ).json() 

这样我们就登录了。


下载记录


接下来,转到music.yandex.ru/user/<user>/history ,我们在其中还选择了一些参数,这些参数在接收有关曲目的信息时对我们有用。 现在您可以下载故事。 我们在music.yandex.ru/handlers/library.jsx使用参数{'owner': <user>, 'filter': 'history', 'likeFilter': 'favorite', 'lang': 'ru', 'external-domain': 'music.yandex.ru', 'overembed': 'false', 'ncrnd': '0.9546193023464256'}获取music.yandex.ru/handlers/library.jsx {'owner': <user>, 'filter': 'history', 'likeFilter': 'favorite', 'lang': 'ru', 'external-domain': 'music.yandex.ru', 'overembed': 'false', 'ncrnd': '0.9546193023464256'} 。 我对这里的ncrnd参数感兴趣。 发出请求时,Yandex始终为该参数分配不同的值,但所有操作均相同。 返回时,我们以id轨道和有关前十个轨道的详细信息的形式获得历史记录。 从详细的跟踪信息中,您可以保存很多有趣的数据以供以后分析。 例如,发行年份,曲目持续时间和类型。 有关其余曲目的信息可从music.yandex.ru/handlers/track-entries.jsx获得。 我们将所有这些业务保存在csv中,然后进行分析。


分析方法


为了进行分析,我们使用pandas和matplotlib形式的标准工具。


 import pandas as pd import matplotlib.pyplot as plt df = pd.read_csv('statistics.csv') df.head(3) 

不行艺术家artist_id专辑album_id追踪track_idduration_sec年份体裁
0酷玩671Viva La Vida-Prospekt的三月版51399死亡和他所有的朋友4757393832008年摇滚乐
1个酷玩671催眠4,175,645催眠340460753552017年摇滚乐
2酷玩671黄色49292不再让我的脚在地上4689452712000摇滚乐

将python的None更改为NaN并将其丢弃。


 df = df.replace('None', pd.np.nan).dropna() 

让我们从一个简单的开始。 让我们看看我们花在听所有曲目上的时间


 duration_sec = df['duration_sec'].astype('int64').sum() ss = duration_sec % 60 m = duration_sec // 60 mm = m % 60 h = m // 60 hh = h % 60 f'{h // 24} {hh}:{mm}:{ss}' 

 '15 15:30:14' 

但是在这里您可以争论这个数字的准确性,因为尚不清楚您需要听​​曲目的哪一部分,Yandex将其添加到了故事中。


现在,让我们看一下发行年份的曲目分布。


 plt.rcParams['figure.figsize'] = [15, 5] plt.hist(df['year'].sort_values(), bins=len(df['year'].unique())) plt.xticks(rotation='vertical') plt.show() 


在这里,事情并不是那么简单,因为“最佳歌曲”的多样化收藏将在下一年推出。


其他统计数据将基于非常相似的原理。 我将举一个听得最多的曲目的例子


 df.groupby(['track_id', 'artist','track'])['track_id'].count().sort_values(ascending=False).head() 

track_id艺术家追踪
170252林肯公园我做了什么32
28472574酷玩向上和向上31
3656360酷玩查理·布朗31
178529林肯公园麻木29日
289675三十秒到火星攻击力27

和该艺术家最常播放的曲目


 artist_name = 'Coldplay' df.groupby([ 'artist_id', 'track_id', 'artist', 'track' ])['artist_id'].count().sort_values(ascending=False)[:,:,artist_name].head(5) 

artist_idtrack_id追踪
67128472574向上和向上31
3656360查理·布朗31
340302修好你26
26285334满脑子的梦想26
376949黄色23

完整的代码可以在这里找到

Source: https://habr.com/ru/post/zh-CN467863/


All Articles