查看原文
其他

播放列表中的歌单排行

爬虫俱乐部 Stata and Python数据分析 2022-03-15

本文作者:石   艳,中南财经政法大学统计与数学学院

本文编辑:张孟晗

技术总编:陈   鼎

Stata&Python云端课程来啦!

       为了感谢大家长久以来的支持和信任,爬虫俱乐部为大家送福利啦!!!Stata&Python特惠课程双双上线腾讯课堂~爬虫俱乐部推出了Python编程培训课程Stata基础课程Stata进阶课程Stata文本分析正则表达式网络爬虫基本字符串课程。报名课程即可加入答疑群,对报名有任何疑问欢迎在公众号后台和腾讯课堂留言哦。我们在这篇推文的最后提供了每门课程的课程二维码,大家有需要的话可以直接扫描二维码查看课程详情并进行购买哦~

引言

当结束一天的学习,你可能会打开手机的音乐播放器,选择喜欢的歌单进行播放;又或者当结束一天的工作之后,你会选择用听音乐来连接公司和家的旅程,不论何种情况,听到喜欢的音乐总是开心和放松的。众多音乐平台上都有歌单分类,可以提供不同场景的音乐选择,今天就带大家看一下网易云音乐的场景歌单排行。


1、数据获取


我们首先打开网易云音乐的歌单栏目,然后选择自己倾向的分类,在此处选择了“地铁”这一场景,获取这一场景下的歌单,观察页面可以发现,每个歌单包含标题、作者、播放量和详情链接这些信息,每页会呈现35个歌单,共38页。查看每一页对应的链接,发现取决于offset这个参数对应的数字,即每增加一页,offset后的数字增加35。
第一页为:
https://music.163.com/#/discover/playlist/order=hot&cat=%E5%9C%B0%E9%93%81&limit=35&offset=0
第二页为:

https://music.163.com/#/discover/playlist/order=hot&cat=%E5%9C%B0%E9%93%81&limit=35&offset=35


我们在上一步只能获取到播放量这一数据信息,点开详情之后可以发现评论量、收藏量、歌单标签、歌单简介等一些信息,这也可以为后面的分析做铺垫。所以数据获取可以分为两步:第一步从歌单首页获取歌单详情链接等信息;第二步利用第一步的链接,再次获取详细信息。

在页面右击检查,选择network之后,刷新页面发现信息位于一个Doc文件当中,结合BeautifulSoup库的一些方法,找到目标信息所在的网页标签,即可实现数据抓取,代码如下:

from bs4 import BeautifulSoupimport requestsimport time
headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36'}
# 主要获取歌单详情的链接for i in range(0, 1295, 35): print("正在抓取第%s页"%(i/35)) time.sleep(3) url = 'https://music.163.com/discover/playlist/?order=hot&cat=%E5%9C%B0%E9%93%81&limit=35&offset=' + str(i) response = requests.get(url=url, headers=headers) html = response.text soup = BeautifulSoup(html, 'html.parser') # 获取包含歌单详情页网址的标签 ids = soup.select('.dec a') # 获取包含歌单索引页信息的标签 lis = soup.select('#m-pl-container li')# print(len(lis)) for j in range(len(lis)): # 获取歌单详情页地址 url = ids[j]['href'] # 获取歌单标题,替换英文分割符 title = ids[j]['title'].replace(',', ',') # 获取歌单播放量 # play = lis[j].select('.nb')[0].get_text() # 获取歌单贡献者名字 user = lis[j].select('p')[1].select('a')[0].get_text() # 输出歌单索引页信息 # print(url, title, play, user) # 将信息写入CSV文件中 with open(r'.\playlist.csv', 'a+', encoding='utf-8-sig') as f: f.write(url + ',' + title + ',' + play + ',' + user + '\n')df = pd.read_csv(r'.\playlist.csv', header=None, error_bad_lines=False, names=['url', 'title', 'play', 'user'])
for i in range(0,len(df['url'])-1): print('正在抓取第%s个歌单信息'%(i+1)) time.sleep(3) url = 'https://music.163.com' + df['url'][i] response = requests.get(url=url, headers=headers) html = response.text soup = BeautifulSoup(html, 'html.parser') # 获取歌单标题 title = soup.select('h2')[0].get_text().replace(',', ',') # 获取标签 tags = [] tags_message = soup.select('.u-tag i') for p in tags_message: tags.append(p.get_text()) # 对标签进行格式化 if len(tags) > 1: tag = '-'.join(tags) else: tag = tags[0] # 获取歌单介绍 if soup.select('#album-desc-more'): text = soup.select('#album-desc-more')[0].get_text().replace('\n', '').replace(',', ',') else: text = '无' # 获取歌单收藏量 collection = soup.select('#content-operation i')[1].get_text().replace('(', '').replace(')', '') # 歌单播放量 play = soup.select('.s-fc6')[0].get_text() # 歌单内歌曲数 songs = soup.select('#playlist-track-count')[0].get_text() # 歌单评论数 comments = soup.select('#cnt_comment_count')[0].get_text() # 输出歌单详情页信息# print(title, tag, text, collection, play, songs, comments) # 将详情页信息写入CSV文件中    with open(r'.\music_message.csv', 'a+', encoding='utf-8-sig') as f:        f.write(title + ',' + tag + ',' + text + ',' + collection + ',' + play + ',' + songs + ',' + comments + '\n')


2、数据可视化

导入上一过程获取到的数据,共1295条,接下来进行可视化,主要采用matplotlib库来展示依据歌单创建者、播放量、收藏量、评论量而得到的榜单TOP10。
import pandas as pdimport numpy as npimport matplotlib.pyplot as plt
df = pd.read_csv(r'.\playlist.csv', header=None, error_bad_lines=False, names=['url', 'title', 'play', 'user'])
2.1最具贡献的歌单创作者
同一个作者可能创建了不同的歌单,那就让我们来看看哪位创建者最勤劳?
# 数据聚合分组place_message = df.groupby(['user'])place_com = place_message['user'].agg(['count'])place_com.reset_index(inplace=True)place_com_last = place_com.sort_index()dom = place_com_last.sort_values('count', ascending=False)[0:10]
# 设置显示数据names = [i for i in dom.user]names.reverse()nums = [i for i in dom['count']]nums.reverse()data = pd.Series(nums, index=names)
# 设置图片显示属性,字体及大小plt.rcParams['font.sans-serif'] = ['Microsoft YaHei']plt.rcParams['font.size'] = 10plt.rcParams['axes.unicode_minus'] = False
# 设置图片显示属性fig = plt.figure(figsize=(16, 8), dpi=80)ax = plt.subplot(1, 1, 1)ax.patch.set_color('white')
# 设置坐标轴属性lines = plt.gca()
# 设置坐标轴颜色lines.spines['right'].set_color('none')lines.spines['top'].set_color('none')lines.spines['left'].set_color((64/255, 64/255, 64/255))lines.spines['bottom'].set_color((64/255, 64/255, 64/255))
# 设置坐标轴刻度lines.xaxis.set_ticks_position('none')lines.yaxis.set_ticks_position('none')
# 绘制柱状图,设置柱状图颜色data.plot.barh(ax=ax, width=0.7, alpha=0.7, color=(153/255, 0/255, 102/255))
# 添加标题,设置字体大小ax.set_title('歌单贡献UP主 TOP10', fontsize=18, fontweight='light')
# 添加歌曲出现次数文本for x, y in enumerate(data.values): plt.text(y+0.3, x-0.12, '%s' % y, ha='center')# 显示图片plt.show()

可以看到“931周小美”以一己之力创作了105个歌单,是排名第二的大约10倍,最具贡献奖非她莫属!


2.2“地铁”场景歌单播放 TOP10
接下来的分析是基于第二步获取的数据集,这个数据集中有些信息不规范,在作图前需要先进行处理。而绘图过程与上文类似,只是绘图对象不同,所以此处只展示选择绘图对象的过程,在此处选择的绘图对象为播放量排名前十的歌单和对应的播放量。
import redf1 = pd.read_csv(r'.\music_message.csv', header=None, error_bad_lines=False, names=['title', 'tag', 'introduce', 'collection', 'play', 'count','comment'])
df1['collection']=df1['collection'].apply(lambda x: str(x).replace('收藏','0'))df1['collection'] = df1['collection'].apply(lambda x: float(re.sub('万','',str(x)))*10000 if str(x).find('万')!=-1 else float(x))df1['play']=df1['play'].apply(lambda x: float(x))df1['count']=df1['count'].apply(lambda x: float(x))df1['comment']=df1['comment'].replace('评论',int(0))df1['comment']=df1['comment'].apply(lambda x: float(x))
names=df1.sort_values(by='play',axis=0,ascending=False)['title'][:10]plays = df1.sort_values(by='play', axis=0,ascending=False)['play'][:10]# 设置显示数据names = [i for i in names]names.reverse()plays = [i for i in plays]plays.reverse()data = pd.Series(plays, index=names)

可以看到排名第一的歌单为‘[我们出发吧]早 这是近日出发路上的音乐早餐’,播放量有6735万,而排名第二的歌单包含“下班”这一词语,真是一早一晚,相得益彰,大家也可以在地铁上享受这两个歌单哦~

2.3“地铁”场景歌单收藏TOP10
names=df1.sort_values(by='collection',axis=0,ascending=False)['title'][:10]collection = df1.sort_values(by='collection', axis=0,ascending=False)['collection'][:10]# 设置显示数据names = [i for i in names]names.reverse()collection = [i for i in collection]collection.reverse()data = pd.Series(collection, index=names)

观察此排行榜的前两名与播放量榜单的前两名是相同的,收藏量为47万和42万。第三名为标题简单粗暴的“李荣浩x薛之谦”歌单,可见标题起的简单直白,自然能够吸引同好收藏关注。

2.4“地铁”场景歌单评论TOP10

names=df1.sort_values(by='comment',axis=0,ascending=False)['title'][:10]comment = df1.sort_values(by='comment', axis=0,ascending=False)['comment'][:10]# 设置显示数据names = [i for i in names]names.reverse()comment = [i for i in comment]comment.reverse()data = pd.Series(comment, index=names)

评论榜单位居第一的为“李荣浩x薛之谦”歌单,而且整个歌单出现的频率与前两个榜单是不同的,也就是说有的人更喜欢听,有的人更喜欢评论分享。

2.5“地铁”场景歌单标签分布

每一个歌单都有一个或多个标签,比如“地铁”、“欧美”等,我们将这些标签根据出现的频率进行分类绘图。
# 处理标签信息
tags = []dom2 = []for i in df1['tag']: c = i.split('-') for j in c: if j not in tags: tags.append(j) else: continue# len(tags)for item in tags: num = 0 for i in df1['tag']: type2 = i.split('-') for j in range(len(type2)): if type2[j] == item: num += 1 else: continue dom2.append(num)# len(dom2)
# 数据创建data = {'tags': tags, 'num': dom2}frame = pd.DataFrame(data)df2 = frame.sort_values(by='num', ascending=False)name = df2['tags'][:10]income = df2['num'][:10]# 绘图detailscolors = ['#993333', '#CC9966', '#333333', '#663366', '#003366', '#009966', '#FF6600', '#FF0033', '#009999', '#333366']plot = squarify.plot(sizes=income, label=name, color=colors, alpha=1, value=income, edgecolor='white', linewidth=1.5)# 设置图片显示属性,字体及大小plt.rcParams['font.sans-serif'] = ['Microsoft YaHei']plt.rcParams['font.size'] = 20plt.rcParams['axes.unicode_minus'] = False# 设置标签大小为1plt.rc('font', size=6)# 设置标题大小plot.set_title('地铁情景歌单标签图', fontsize=20, fontweight='light')# 除坐标轴plt.axis('off')# 除上边框和右边框刻度plt.tick_params(top=False, right=False)# 图形展示plt.show()

从图中可以发现除了“地铁”这一初始标签以外,“流行”、“驾车”、“学习”这些标签出现的次数也很多,说明地铁这一分类下的歌单中的歌也适合以上提到的场景。

今天的内容分享就到这儿了,希望大家能够找到自己喜欢的歌单,让无聊的场景变得稍微有趣一点~



最后,我们为大家揭秘雪球网(https://xueqiu.com/)最新所展示的沪深证券和港股关注人数增长Top10。



腾讯课堂课程二维码








                


 对我们的推文累计打赏超过1000元,我们即可给您开具发票,发票类别为“咨询费”。用心做事,不负您的支持!











往期推文推荐

        在Stata中轻松运用program编写命令

         Meta Analysis in Stata17      

芒果TV视频弹幕爬取之《我在他乡挺好的》

Stata中的判断神器——confirm命令

cngdf——名义GDP与实际GDP之间的摆渡船

最近《扫黑风暴》有点火爆!我从豆瓣评论中发现了这些……

随机森林-Random Forest 

复原之神--preserve&restore

         合并,“纵”享新丝滑:frameappend & xframeappend
什么是全局配置项?|从零开始的Pyecharts(二)帮你拿下数据可视化|从零开始的Pyecharts 

Stata助力疫情打卡管理——是谁没有接龙呢?

这十年,《金融研究》的编委和读者偏爱哪些研究话题和文章?

【案例展示】Python与数据库交互

学好这一手,英语词典常在手 

玩转Stata中的数学函数

用spmap看中国空气质量

戳穿围城面具:安利&劝退一个专业

走进图文并茂的攻略世界 

玩转word文档“大变身”——wordconvert

数据读入|一文读懂用Stata读入不同类型的数据

简述递归

OpenCV库——轻松更换证件照背景色

800万年薪!还有谁?!

千古伤心词人,词伤几何?

去哪儿网攻略爬取——跟我一起去大理吧

"有你才有团"——Stata爬取王者荣耀英雄海报

爬虫实战|嚣张的徽州宴老板娘错在哪?

如何获取衡量股民情绪的指标?|东方财富股吧标题爬虫

利用Python构建马科维茨有效边界

rangestat,让统计量灵活滚动起来!

关于我们 


   微信公众号“Stata and Python数据分析”分享实用的Stata、Python等软件的数据处理知识,欢迎转载、打赏。我们是由李春涛教授领导下的研究生及本科生组成的大数据处理和分析团队。

   武汉字符串数据科技有限公司一直为广大用户提供数据采集和分析的服务工作,如果您有这方面的需求,请发邮件到statatraining@163.com,或者直接联系我们的数据中台总工程司海涛先生,电话:18203668525,wechat: super4ht。海涛先生曾长期在香港大学从事研究工作,现为知名985大学的博士生,爬虫俱乐部网络爬虫技术和正则表达式的课程负责人。



此外,欢迎大家踊跃投稿,介绍一些关于Stata和Python的数据处理和分析技巧。

投稿邮箱:statatraining@163.com投稿要求:
1)必须原创,禁止抄袭;
2)必须准确,详细,有例子,有截图;
注意事项:
1)所有投稿都会经过本公众号运营团队成员的审核,审核通过才可录用,一经录用,会在该推文里
为作者署名,并有赏金分成。

2)邮件请注明投稿,邮件名称为“投稿+推文名称”。
3)应广大读者要求,现开通有偿问答服务,如果大家遇到有关数据处理、分析等问题,可以在公众
号中提出,只需支付少量赏金,我们会在后期的推文里给予解答。




您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存