Python告诉你:从《入海》到《消愁》毛不易的歌里都在唱些什么?

【导语】:今天我们来聊聊——B站联合毛不易发布的毕业季主题曲《入海》,以及背后不一样的毛不易。Python技术部分请看第三部分。

Show me data,用数据说话!今天我们聊一聊 毛不易的《入海》,没错,还是那个B站,在520这个既浪漫且有营销价值的一天又「搞事情」了。

5月20日, B站联合毛不易发布毕业季主题曲《入海》。这首歌主题是“献给即将或已经毕业的人们”,歌曲MV中以主人公毕业的时候为原点,追忆过去,并用大量篇幅展现普通人毕业后的社会生活。

这首歌一经发布就在B站引爆了话题点,截止到5月24日在B站播放量达到了800万+,收获了5.2万弹幕,最高全站日排行1名。


今天我们就带你来解读这首《入海》,以及背后不一样的毛不易。

01、毛不易的歌里,都喜欢唱些什么?

毛不易,本名王维家。本来毕业于杭州师范大学护理专业的他一直有个歌手梦。在2017年,参加腾讯视频选秀音乐娱乐节目《明日之子》,获得全国总决赛冠军,从而正式进入演艺圈。谁又能想到最后拿到冠军是这个长相平平,没有什么优势,甚至有点害羞憨厚的毛不易了。

随着《消愁》《像我这样的人》等歌曲的大火,毛不易这个名字也被越来越多的人知晓。同时在今年鹅厂的女团选秀节目《创造营2020》中,毛不易更是以导师的身份加入,呆萌的毛老师这次也收获了不少的粉丝。

听着《消愁》里的“一杯敬朝阳,一杯敬月光“,大概是因为才华,毛不易在这个年纪能写出人生的无奈和纠葛,这是一种大的勇气。


那么毛不易的歌里都在唱些什么呢?下面让我们来盘一盘:

我们分析整理了毛不易在网易云音乐的歌曲,一共83首,歌词字数加起来45577字,我们用Python对这些歌词进行分析。

歌曲时长分布

首先在歌曲时长方面,时长为4-5分钟的最多高达43.9%,3-4分钟为29.27%,2-3分钟的为13.41%。要知道一般歌曲时长多为3分钟左右,看来毛不易的歌时长还是偏长的。


歌曲正向情感得分


我们使用boson库对每首歌的歌词的情感进行打分,分数介于0~100分,高于50分为积极,分数越高,积极倾向性越高。从分布图可以看出,在83首歌曲中,大部分的歌曲正向积极情感为主。

毛不易最喜欢的词TOP15


毛不易最喜欢的歌里最喜欢用哪些词呢?我们分析整理得出了歌词中出现频率最高的TOP15。可以看到"等待"、"生活"、"时光"等词出现频率最高,位列前三。


"慢慢"、"遇见"、"江水"、"角落"等比较文艺的词也上榜了。有意思的是"有钱"出现频率也较高,位列第四。

02、《入海》全站日排名第一,这首献给毕业季的歌好在哪儿?


我们使用Python获取并分析了B站上《入海》这首MV的评论数据,经过去重之后得到19099条样本,下面让我们看到评论的具体分析。

评论用户性别占比

首先,在评论用户性别占比方面,男性用户占比略高,男性用户占比54.69%,女性用户占比45.31%。


评论用户客户端分布

那么看《入海》的用户在看视频时都用的什么移动设备呢?经过分析发现,用iphone的用户占了很大的比例,远超Andrio系统的用户。第三位是使用ipad的用户。


评论用户等级分布

同时我们知道,b站上用户因为参与程度等因素,等级从0-6分布,数字越大等级越高。在《入海》这首歌的评论用户上,评论中5级的占比最高为36.1%,其次是4级占比26.31%,6级占比仅为3.24%,这也是因为毕竟要成为六级大佬实在太难了。


各时段评论人数


在评论时间段方面,《入海》是在5月20日 8:30发布的,在发布后评论的人数越来越多,在12点左右评论达到最高峰,这个时段共有2万7千余人进行评论,远高于其他时段,之后随着时间推移评论人数也越来越少,趋于平缓。

评论关键词TOP15

在评论中大家说得最多的是什么呢?


经过分析整理可以看到,"毕业"是提到最多的词,其次第二位是"后浪",毕竟作为同样聚焦在年轻人身上的话题,这次的《入海》很容易让大家联系到5月4日B站发布的《后浪》视频。


同时,"快乐"、"入海"、"大哭"等词也被频频提到。

03、Python分析:B站《入海》评论数据

我们使用Python获取并分析了B站上《入海》这首MV的评论数据。经过去重之后得到19099条样本,来分析一下这周MV的用户的评论信息。整个分析流程分为以下几步:

数据获取数据整理数据可视化

数据获取

在获取视频评论之前,我们首要做的就是分析其网页结构,寻找目标数据,也就是我们要评论的数据在哪里。


经过抓包分析,在network-json选项卡下,很容易找到了数据传输的地址,经过分析和精简,目标数据的url链接为:

https://api.bilibili.com/x/v2/reply?&type=1&oid=795637027&pn=1

其中oid是视频的专属oid,pn是页面数。

由上图可看出,其评论数据是以json数据形式存在于网页端的,目前显示的页数是976页,每页20条评论,追评数据暂时不做抓取。

接下来,就爬取思路很明确,从第一页的JSON文件开始,爬完20条评论,循环pn页数,直到爬完所有的评论数据。

代码如下:

# 导入所需包import requestsimport jsonimport pandas as pdimport timedef get_bili_comment_one(url): """ 功能:定义函数,获取一页的信息 """ # 添加headers headers = { 'Host': 'api.bilibili.com', 'Referer': 'https://www.bilibili.com/video/BV1YZ4y1j7s5', 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.149 Safari/537.36' } # 添加cookies cookies = { "cookie": "复制您的浏览器cookie信息" } # 发起请求 try: r = requests.get(url, headers=headers, cookies=cookies, timeout=3) except Exception as e: print(e) r = requests.get(url, headers=headers, cookies=cookies, timeout=3) # 解析为字典 r_json = json.loads(r.text) # 提取信息 replies_data = r_json['data']['replies'] # 用户名 user_name = [i['member'].get('uname') for i in replies_data] # 性别 sex = [i['member'].get('sex') for i in replies_data] # 签名 sign = [i['member'].get('sign') for i in replies_data] # 用户等级 current_level = [i['member']['level_info'].get('current_level') for i in replies_data] # 评论内容 content = [i['content'].get('message') for i in replies_data] # 用户设备 device = [i['content'].get('device') for i in replies_data] # 评论时间 content_time = [i.get('ctime') for i in replies_data] # 回复数 reply_count = [i['rcount'] for i in replies_data] # 存储数据 df = pd.DataFrame({ 'user_name': user_name, 'sex': sex, 'sign': sign, 'current_level': current_level, 'content': content, 'device': device, 'content_time': content_time, 'reply_count': reply_count }) return dfdef get_bili_comment_all(oid, num): """ 功能:定义函数,获取B站视频指定页评论信息 """ # 循环构建URL df_all = pd.DataFrame() for page_num in range(1, num): try: # 构建URL url = 'https://api.bilibili.com/x/v2/reply?&pn={}&type=1&oid={}&sort=2'.format(page_num, oid) # 调用函数 df = get_bili_comment_one(url) # 判断 if df.shape[0] == 0: break else: # 循环追加 df_all = df_all.append(df, ignore_index=True) # 打印进度 print('我正在获取第{}页的信息'.format(page_num)) except: break # 休眠一秒 time.sleep(0.5) return df_all# 《入海》bilibili X 毛不易 | 跃入人海,各有风雨灿烂df = get_bili_comment_all(oid='795637027', num=973)

获取到的数据以DataFrame的形式存储,格式如下:

# 读入数据df.head()


数据集有19099个样本,8个字段,字段名称为:用户名、用户性别、用户签名、用户等级、用户评论、设备名称、评论时间、点赞数。

df.info()

<class 'pandas.core.frame.DataFrame'>RangeIndex: 19099 entries, 0 to 19098Data columns (total 8 columns):user_name 19099 non-null objectsex 19099 non-null objectsign 9896 non-null objectcurrent_level 19099 non-null int64content 19099 non-null objectdevice 4159 non-null objectcontent_time 19099 non-null int64reply_count 19099 non-null int64dtypes: int64(3), object(5)memory usage: 1.2+ MB

数据整理

此处我们主要对以上获取的数据集进行部分清洗工作以方便后续的处理:

重复值处理类型转化时间戳数据处理评论数据jieba分词处理-(代码暂略)

# 导入包import numpy as np import pandas as pd# 读入数据df = pd.read_excel('../data/B站评论数据-入海5.23.xlsx')# 去重df = df.drop_duplicates()# 转换类型df['content'] = [str(i) for i in df.content] # 定义转换时间def transform_timestamp(time_second): timeArray = time.localtime(time_second) otherStyleTime = time.strftime('%Y-%m-%d %H:%M:%S', timeArray) return otherStyleTime# 提取时间df['content_time'] = df['content_time'].apply(lambda x:transform_timestamp(x))

数据可视化分析

我们将进行以下部分的数据可视化分析,首先导入所需包,其中pyecharts用于绘制动态图形,stylecloud用于绘制词云图,关键代码如下:

from pyecharts.charts import Bar, Pie, Line, WordCloud, Pagefrom pyecharts import options as opts from pyecharts.globals import SymbolTypeimport stylecloudfrom IPython.display import Image

评论性别占比

# 总体评分分布sex_num = df['sex'].value_counts()sex_num.drop('保密', inplace=True) # 绘制饼图data_pair = [list(z) for z in zip(sex_num.index.tolist(), sex_num.values.tolist())]# 绘制饼图pie1 = Pie(init_opts=opts.InitOpts(width='1350px', height='750px'))pie1.add('', data_pair, radius=['35%', '60%'])pie1.set_global_opts(title_opts=opts.TitleOpts(title='评论用户性别占比'), legend_opts=opts.LegendOpts(orient='vertical', pos_top='15%', pos_left='2%'))pie1.set_series_opts(label_opts=opts.LabelOpts(formatter="{b}:{d}%"))pie1.set_colors(['#EF9050', '#3B7BA9', '#6FB27C'])pie1.render()

用户客户端分布

device_num = df.device.value_counts(ascending=True) # 柱形图bar1 = Bar(init_opts=opts.InitOpts(width='1350px', height='750px'))bar1.add_xaxis(device_num.index.tolist())bar1.add_yaxis('', device_num.values.tolist(), label_opts=opts.LabelOpts(position='right'))bar1.set_global_opts(title_opts=opts.TitleOpts(title='评论客户端分布'), visualmap_opts=opts.VisualMapOpts(max_=3000))bar1.reversal_axis()bar1.render()

用户等级分布

# 用户等级level_num = df.current_level.value_counts()data_pair2 = [list(z) for z in zip(['LV' + i for i in level_num.index.astype('str').tolist()] , level_num.values.tolist())]# 绘制饼图pie2 = Pie(init_opts=opts.InitOpts(width='1350px', height='750px'))pie2.add('', data_pair=data_pair2, radius=['35%', '60%'])pie2.set_global_opts(title_opts=opts.TitleOpts(title='评论用户等级分布'), legend_opts=opts.LegendOpts(orient='vertical', pos_top='15%', pos_left='2%'))pie2.set_series_opts(label_opts=opts.LabelOpts(formatter="{b}:{c}({d}%)"))pie2.set_colors(['#EF9050', '#3B7BA9', '#6FB27C', '#FFAF34'])pie2.render()

评论时间走势图

# 时间数据处理df['time'] = df.content_time.str.split('-').str[1] + '-' + df.content_time.str.split('-').str[2]df['time'] = df.time.str.split(':').str[0]time_num = df.time.value_counts().sort_index()# 产生数据x1_line1 = time_num.index.values.astype('str').tolist()y1_line1 = time_num.values.tolist() # 绘制面积图line1 = Line(init_opts=opts.InitOpts(width='1350px', height='750px'))line1.add_xaxis(x1_line1)line1.add_yaxis('', y1_line1, areastyle_opts=opts.AreaStyleOpts(opacity=0.3), markpoint_opts=opts.MarkPointOpts(data=[ opts.MarkPointItem(type_='max', name='最大值') ])) line1.set_global_opts(title_opts=opts.TitleOpts('各个时段评论人数'), xaxis_opts=opts.AxisOpts(axislabel_opts=opts.LabelOpts(rotate='30')) ) line1.set_series_opts(label_opts=opts.LabelOpts(is_show=False), axisline_opts=opts.AxisLineOpts() )line1.render()

评论词云图


import stylecloudfrom IPython.display import Image # 用于在jupyter lab中显示本地图片stylecloud.gen_stylecloud(text=' '.join(word_num), # txt需要传入str格式 collocations=False, font_path=r'C:\Windows\Fonts\msyh.ttc', icon_name='fas fa-graduation-cap', size=768, output_name='B站评论词云图.png')Image(filename='B站评论词云图.png')

原文链接:https://baijiahao.baidu.com/s?id=1667723272482255770&wfr=spider&for=pc

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,560评论 4 361
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,104评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,297评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,869评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,275评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,563评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,833评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,543评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,245评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,512评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,011评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,359评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,006评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,062评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,825评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,590评论 2 273
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,501评论 2 268