2020年7月17日
最近网抑云好火,随便听一首歌打开评论基本都是非常丧文化的评论,所以突发奇想,想获取一个用户的个人歌单,当然,如果这个人的歌单是公开的话才可以(怂),然后分析这群吊毛到底是不是抑郁症。
其实还有就是以后推荐我歌曲分享给朋友的时候要投其所好
针对上面两种想法突发奇想准备开发一个小工具
重点·刘杰非常尊重抑郁症患者,但是借抑郁症的噱头逃避现实无病呻吟的就算了吧。。。所以,开始吧。
目标功能:
- 输入关键字弹出用户列表
- 选择具体用户
- 获取用户最近一周听歌排行与每首歌曲听的次数
- 获取用户的“我喜欢”歌单的最近100首歌曲列表
- 获取用户所有时间的听歌排行列表
- 分析用户的“我喜欢”歌单的最近100首歌曲的分类报表
分析用户实现步骤逻辑:
- 根据用户名搜索用户
- 搜索该用户的歌单循环遍历
2.1. 每首歌的所在的热门歌单
2.2. 获取该歌单的分类 - 将报表作为饼图/柱状图展示
已知条件
根据用户名搜索用户
https://music.163.com/#/search/m/?s=关键字&type=1002
搜索该用户的歌单
https://music.163.com/#/user/home?id=用户ID
每首歌的所在的热门歌单
https://music.163.com/#/song?id=歌曲ID
获取该歌单的分类
https://music.163.com/#/playlist?id=歌单ID
2020年7月18日
肝出来了一些,先发出来:
#coding:utf-8
from bs4 import BeautifulSoup
from winreg import HKEY_CURRENT_USER as HKEY_CURRENT_USER
from winreg import OpenKey as OPENKEY
from winreg import QueryValueEx as QUERYVALUEEX
from pandas import DataFrame as DataFrame
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
# 通用方法:得到自动测试浏览器执行实例
def getDriver():
chrome_options = Options()
chrome_options.add_argument('--headless')
#未配置环境变量,如果配置了chrome_driver的环境变量则可以不要该行代码
chrome_driver = 'D:\IsMy\chromedriver\chromedriver.exe'
driver = webdriver.Chrome(executable_path=chrome_driver, options=chrome_options)
return driver
# 通用方法:根据网易云链接+参数href得到页面解析后的源码
def getSourcePageByHref(href):
driver = getDriver()
driver.get("https://music.163.com/#" + href)
# 切换frame
driver.switch_to.frame("g_iframe")
soup = BeautifulSoup(driver.page_source)
# 关闭浏览器
driver.quit()
return soup
# 输入关键字弹出用户列表
def getUserlist(userWord):
driver = getDriver()
driver.get("https://music.163.com/#/search/m/?s=" + userWord + "&type=1002")
# 切换frame
driver.switch_to.frame("g_iframe")
soup = BeautifulSoup(driver.page_source)
# 关闭浏览器
driver.quit()
for item in soup.findAll("div", {"class": "ttc"}): # 这个格式应该参考网易云用户列表布局
href = item.find('a').get("href")
userId = href[14:len(href)]
print(userId+" : "+item.find('a').get("title"))
return userId
# 获取用户最近一周听歌排行与每首歌曲听的次数
def getUserLikeMusicListByWeek(tops,userId):
musicList = []
driver = getDriver()
driver.get("https://music.163.com/#/user/songs/rank?id="+userId)
# 切换frame
driver.switch_to.frame("g_iframe")
soup = BeautifulSoup(driver.page_source)
# 关闭浏览器
driver.quit()
x = 1
for item in soup.findAll("div",{"class":"ttc"}): # 这个格式应该参考网易云用户列表布局
if(x>tops):
break
music = dict()
music.setdefault("name",item.find("b").get("title"))
music.setdefault("href", item.find("a").get("href"))
music.setdefault("author", item.find("a",{"class":"s-fc8"}).getText())
musicList.append(music)
x = x+1
return musicList
# 获取一首歌所在的歌单
def getSongSheetMusicHref(musicHref):
sheetList = []
soup = getSourcePageByHref(musicHref)
for item in soup.findAll("div",{"class":"info"}): # 这个格式应该参考网易云用户列表布局
music = dict()
music.setdefault("name", item.find("a",{"class","sname"}).get("title"))
music.setdefault("href", item.find("a", {"class", "sname"}).get("href"))
sheetList.append(music)
return sheetList
# 网易没有给歌儿进行分类,但是歌单是有标签的,只能找这首歌所在的热门歌单了
# 根据歌单ID获取该歌单标签
def getTagNameBySheetHref(sheetHref):
tagList = []
soup = getSourcePageByHref(sheetHref)
for item in soup.findAll("a", {"class": "u-tag"}): # 这个格式应该参考网易云用户列表布局
tagList.append(item.getText())
return tagList
# 前端方法 选择具体用户
# 获取用户的“我喜欢”歌单的最近100首歌曲列表
# 获取用户所有时间的听歌排行列表
# 分析用户的“我喜欢”歌单的最近100首歌曲的分类报表
#获得系统桌面
def get_desktop():
key = OPENKEY(HKEY_CURRENT_USER,r'Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders',)
return QUERYVALUEEX(key, "Desktop")[0]
def createExcel(data,fileName):
df = DataFrame(data)
# 不输出序号(索引)列
df.to_excel(fileName , sheet_name = "sheet1", index = False, header = True)
运行测试
#coding:utf-8
import numpy as np
import com.dy.methods.BackMethods as bm
class Tag:
def __init__(self, name, count):
self.name = name
self.count = count
def start():
tagList = []
musicList = bm.getUserLikeMusicListByWeek(10, bm.getUserlist("沐青依旧"))
for musicItem in musicList :
sheetList = bm.getSongSheetMusicHref(musicItem.get("href"))
for sheetItem in sheetList:
tagList.extend(bm.getTagNameBySheetHref(sheetItem.get("href")))
tagListCountList = []
# 去重
uniqueTagNameList = np.unique(tagList)
for tagName in uniqueTagNameList:
tagListCountList.append(Tag(tagName, tagList.count(tagName)))
tagListCountList.sort(key=lambda t: t.count, reverse=True) # 按出现次数排序
for tagItem in tagListCountList:
print("标签:"+tagItem.name+" -- 出现的次数:"+str(tagItem.count))
start()
运行结果:
自学的python所以可能有很多地方不合规范,各位大佬如果有时间无比帮我指出来,感恩感恩感恩