Skip to content

Instantly share code, notes, and snippets.

@Xoma163
Created December 2, 2022 08:54
Show Gist options
  • Save Xoma163/1d54a5e5038a40df6981a4e319ccc28e to your computer and use it in GitHub Desktop.
Save Xoma163/1d54a5e5038a40df6981a4e319ccc28e to your computer and use it in GitHub Desktop.
Скрипт выводящий таблицу пересечений интересов на основе песен из яндекс музыки. Вертикаль - относительно вас, горизонталь - относительно других
import requests
from bs4 import BeautifulSoup
class User:
BASE_URL = "https://music.yandex.ru/users/yamusic-2022/playlists/"
def __init__(self, name: str, user_id: int = None, login: str = None):
"""
:param name: Читаемое имя пользователя
:param user_id: https://music.yandex.ru/users/yamusic-2022/playlists/{{ user_id }}
:param login: https://music.yandex.com/users/{{ login }}/playlists/3
"""
if user_id is None and login is None:
raise RuntimeError("user_id or login must be provided")
self.name = name
self.user_id = user_id
self.track_hrefs = []
self.login = login
def set_track_hrefs(self, track_hrefs):
self.track_hrefs = track_hrefs
@property
def playlist_url(self):
return f"{self.BASE_URL}{self.user_id}"
def __str__(self):
return self.name
class YandexMusicIntersection:
def __init__(self, users: list):
self.users = users
self.intersection_table = []
@staticmethod
def _calculate_intersection(track_hrefs1: list, track_hrefs2: list) -> float:
intersection_count = 0
for track in track_hrefs1:
if track in track_hrefs2:
intersection_count += 1
return intersection_count / len(track_hrefs1)
def _make_intersection_table(self):
for user1 in self.users:
intersection_row = []
for user2 in self.users:
if user1 == user2:
res = '-\t'
else:
intersection = self._calculate_intersection(user1.track_hrefs, user2.track_hrefs)
res = f"{round(intersection * 100, 2)}%"
intersection_row.append(res)
self.intersection_table.append(intersection_row)
def calculate(self):
self._set_users_track_hrefs()
self._make_intersection_table()
def print_intersection_table(self):
max_tabs = max([len(x.name) for x in self.users]) // 4 + 1
print(end=max_tabs * '\t')
for user in self.users:
print(user.name, end='\t')
print()
for i, row in enumerate(self.intersection_table):
username = self.users[i].name
_end = (max_tabs - (len(username) // 4)) * '\t'
print(username, end=_end)
for item in row:
print(item, end='\t')
print()
@staticmethod
def _set_users_track_hrefs():
raise NotImplementedError
class Playlist2022YandexMusicIntersection(YandexMusicIntersection):
@staticmethod
def _set_users_track_hrefs():
with requests.session() as s:
for user in users_list:
r = s.get(user.playlist_url)
bs4 = BeautifulSoup(r.content, 'html.parser')
track_hrefs = [x.attrs['href'] for x in bs4.select("a.d-track__title")]
user.set_track_hrefs(track_hrefs)
def _make_intersection_table(self):
print("Таблица пересечений по песням 2022")
super()._make_intersection_table()
class PlaylistLikedYandexMusicIntersection(YandexMusicIntersection):
@staticmethod
def _set_users_track_hrefs():
with requests.session() as s:
for user in users_list:
r = s.get("https://music.yandex.ru/handlers/playlist.jsx", params={
'owner': user.login,
'kinds': 3,
'light': 'true'
})
user.set_track_hrefs(r.json()['playlist']['trackIds'])
def _make_intersection_table(self):
print("Таблица пересечений по любимым песням")
super()._make_intersection_table()
if __name__ == "__main__":
users_list = [
User("Иван", 1),
User("Михаил", 2)
]
y2022i = Playlist2022YandexMusicIntersection(users_list)
y2022i.calculate()
y2022i.print_intersection_table()
print()
print()
users_list = [
User("Иван", login="Ivan1337"),
User("Михаил", login="Mishok77")
]
y2022i = PlaylistLikedYandexMusicIntersection(users_list)
y2022i.calculate()
y2022i.print_intersection_table()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment