نحن نحلل تاريخ الاستماع في Yandex.Music

منذ عام تقريبًا أستخدم خدمة Yandex Music وكل شيء يناسبني. ولكن هناك صفحة واحدة مثيرة للاهتمام في هذه الخدمة - التاريخ. يخزن جميع المسارات التي تم الاستماع إليها في الترتيب الزمني. وبالطبع ، أردت تنزيله وتحليل ما سمعته هناك طوال الوقت.



المحاولات الأولى


بدأت في التعامل مع هذه الصفحة ، واجهت مشكلة على الفور. لا تقوم الخدمة بتنزيل جميع المسارات مرة واحدة ، ولكن فقط أثناء التمرير. لم أكن أرغب في تنزيل الشم وفهم حركة المرور ، ولم يكن لدي أي مهارات في هذا الأمر في ذلك الوقت. لذلك ، قررت أن أذهب ببساطة أكثر عن طريق محاكاة المتصفح باستخدام السيلينيوم.


تم كتابة السيناريو. لكنه عمل غير مستقر للغاية ولفترة طويلة. لكنه نجح في تحميل القصة. بعد تحليل بسيط ، تركت النص بدون تعديلات ، حتى بعد مرور بعض الوقت لم أكن أرغب في تنزيل القصة. على أمل الأفضل ، أطلقته. وبالطبع أخطأ. ثم أدركت أن الوقت قد حان للقيام بكل شيء إنسانيًا.


خيار العمل


لتحليل حركة المرور ، اخترت Fiddler لنفسي بسبب وجود واجهة أكثر قوة لحركة المرور http ، على عكس wireshark. تشغيل الشم ، كنت أتوقع أن أرى طلبات 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 في 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 دائمًا بتعيين قيم مختلفة لهذه المعلمة ، ولكن كل شيء يعمل بنفس الطريقة. مرة أخرى نحصل على السجل في شكل مسارات معرف ومعلومات تفصيلية حول أفضل عشرة مسارات. من معلومات المسار التفصيلية ، يمكنك حفظ الكثير من البيانات المثيرة للاهتمام لتحليلها لاحقًا. على سبيل المثال ، سنة الإصدار ، مدة التتبع والنوع. يتم الحصول على معلومات عن بقية المسارات من music.yandex.ru/handlers/track-entries.jsx . نحن نحفظ كل هذا العمل في ملف CSV وننتقل إلى التحليل.


تحليل


للتحليل ، نستخدم الأدوات القياسية في شكل الباندا و 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's March Edition51399الموت وجميع أصدقائه4757393832008صخرة
1كولدبلاي671منوم4175645منوم340460753552017صخرة
2كولدبلاي671أصفر49292لا مزيد من حفظ قدمي على الأرض4689452712000صخرة

تغيير لا شيء الثعبان ل 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' 

ولكن هنا يمكنك الجدال حول دقة هذا الرقم ، لأنه ليس من الواضح أي جزء من المسار تحتاج إلى الاستماع إليه ، أضافه ياندكس إلى القصة.


الآن دعونا نلقي نظرة على توزيع المسارات حسب سنة الإصدار.


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


هنا ، الأمر نفسه ليس بهذه البساطة ، حيث أن المجموعات المتنوعة من "Best Hits" سيكون لها عام لاحق.


سيتم بناء إحصائيات أخرى على مبدأ مشابه جدًا. سأقدم مثالاً على أكثر المسارات استمعًا


 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ثلاثون ثانية إلى المريخATTACK27

ومعظم المسارات لعبت للفنان


 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/ar467863/


All Articles