MOJITO

最近一直啥都没写,追个热点都赶不上热乎的,鄙视自己一下。

周董的新歌 「MOJITO」 发售(6 月 12 日的零点)至今大致过去了一周,翻开 B 站 MV 一看,播放量妥妥破千万,弹幕破十万,这人气还真是杠杠的。

说实话, 「MOJITO」 这个名字对我来讲有点超纲了,第一次见到完全不知道啥意思。

不过问题不大,没有什么是百度解决不了的,如果有,那就再加一个知乎。

MOJITO 的中文名是莫吉托,百度百科上是这么介绍莫吉托的:

莫吉托(Mojito)是最有名的朗姆调酒之一。起源于古巴。传统上,莫吉托是一种由五种材料制成的鸡尾酒:淡朗姆酒、糖(传统上是用甘蔗汁)、莱姆(青柠)汁、苏打水和薄荷。最原始的古巴配方是使用留兰香或古巴岛上常见的柠檬薄荷。莱姆(青柠)与薄荷的清爽口味是为了与朗姆酒的烈性相互补,同时也使得这种透明无色的调酒成为夏日的热门饮料之一。这种调酒有着相对低的酒精含量(大约10%)。

酒精度数在 10% 左右的话,姑且可以认为一种饮料吧。

当然,如果要开车的话就不能把 MOJITO 当成饮料了,酒精含量再低那也是酒精。

整个 MV 我翻来覆去的看了好几遍, 「MOJITO」 这个东西除了在歌词和名字中有出现,在 MV 当中一次都没出现,毫无存在感。

爬取 B 站弹幕

弹幕数据的爬取比较简单,我就不一步一步的抓请求给各位演示了,注意下面这几个请求连接:

弹幕请求地址:

https://api.bilibili.com/x/v1/dm/list.so?oid=XXX

https://comment.bilibili.com/XXX.xml

第一个地址由于 B 站的网页做了更换,现在在 Chrome 工具的 network 里面已经找不到了,不过还可以用,这个是我之前找到的。

第二个地址来源于百度,我也不知道各路大神是从哪找出来这个地址的,供参考吧。

上面这两个弹幕地址实际上都需要一个叫 oid 的东西,这个 oid 获取方式如下:

首先可以找到一个目录页接口:

https://api.bilibili.com/x/player/pagelist?bvid=XXX&jsonp=jsonp

这个接口也是来源于 Chrome 的 network ,其中 bvid 这个参数来源于视频地址,比如周董的这个 「MOJITO」 的 MV ,地址是 https://www.bilibili.com/video/BV1PK4y1b7dt ,那么这个 bvid 的值就是最后那一部分 BV1PK4y1b7dt

接下来在 https://api.bilibili.com/x/player/pagelist?bvid=BV1PK4y1b7dt&jsonp=jsonp 这个接口中,我们可以看到返回的 json 参数,如下:

{
"code":0,
"message":"0",
"ttl":1,
"data":[
{
"cid":201056987,
"page":1,
"from":"vupload",
"part":"JAY-MOJITO_完整MV(更新版)",
"duration":189,
"vid":"",
"weblink":"",
"dimension":{
"width":1920,
"height":1080,
"rotate":0
}
}
]
}

注意:由于这个 MV 只有一个完整的视频,所以这里只有一个 cid ,如果一个视频是分不同小节发布的,这里就会有多个 cid ,不同的 cid 代表不同的视频。

当然,这里的 cid 就是我们刚才想找的那个 oid ,把这个 cid 拼到刚才的链接上,可以得到 https://api.bilibili.com/x/v1/dm/list.so?oid=201056987 这样一个地址,然后输入到浏览器中,可以看到弹幕的返回数据,是一个 xml 格式的文本。

源代码如下:

import requests
import re # 获取 cid
res = requests.get("https://api.bilibili.com/x/player/pagelist?bvid=BV1PK4y1b7dt&jsonp=jsonp")
cid = res.json()['data'][0]['cid'] # 将弹幕 xml 通过正则取出,生成 list
danmu_url = f"https://api.bilibili.com/x/v1/dm/list.so?oid={cid}"
result = requests.get(danmu_url).content.decode('utf-8')
pattern = re.compile('<d.*?>(.*?)</d>')
danmu_list = pattern.findall(result) # 将弹幕 list 保存至 txt 文件
with open("dan_mu.txt", mode="w", encoding="utf-8") as f:
for item in danmu_list:
f.write(item)
f.write("\n")

这里我将获取到的弹幕保存在了 dan_mu.txt 文件中,方便后续分析。

绘制词云图

第一步先将刚才保存在 dan_mu.txt 文件中的弹幕读取出来,放到了一个 list 当中:

# 读取弹幕 txt 文件
with open("dan_mu.txt", encoding="utf-8") as f:
txt = f.read()
danmu_list = txt.split("\n")

然后使用分词工具对弹幕进行分词,我这里使用的分词工具是最好的 Python 中文分词组件 jieba ,没有安装过 jieba 的同学可以使用以下命令进行安装:

pip install jieba

使用 jieba 对刚才获得的弹幕 list 进行分词:

# jieba 分词
danmu_cut = [jieba.lcut(item) for item in danmu_list]

这样,我们获得了分词后的 danmu_cut ,这个同样是一个 list 。

接着我们对分词后的 danmu_cut 进行下一项操作,去除停用词:

# 获取停用词
with open("baidu_stopwords.txt",encoding="utf-8") as f:
stop = f.read()
stop_words = stop.split() # 去掉停用词后的最终词
s_data_cut = pd.Series(danmu_cut)
all_words_after = s_data_cut.apply(lambda x:[i for i in x if i not in stop])

这里我引入了一个 baidu_stopwords.txt 文件,这个文件是百度停用词库,这里我找到了几个常用的中文停用词库,来源: https://github.com/goto456/stopwords

词表文件 词表名
baidu_stopwords.txt 百度停用词表
hit_stopwords.txt 哈工大停用词表
scu_stopwords.txt 四川大学机器智能实验室停用词库
cn_stopwords.txt 中文停用词表

这里我使用的是百度停用词表,大家可以根据自己的需要使用,也可以对这几个停用词表先做整合后再使用,主要的目的就是去除一些无需关注的词,上面这几个停用词库我都会提交到代码仓库,有需要的自取。

接着我们统计去除停用词后的词频:

# 词频统计
all_words = []
for i in all_words_after:
all_words.extend(i)
word_count = pd.Series(all_words).value_counts()

最后一步就是生成我们的最终结果,词云图:

wordcloud.WordCloud(
font_path='msyh.ttc',
background_color="#fff",
max_words=1000,
max_font_size=200,
random_state=42,
width=900,
height=1600
).fit_words(word_count).to_file("wordcloud.png")

最终结果就是下面这个:

从上面这个词云图中可以看到,粉丝对「MOJITO」这首歌是真爱啊,出现频率最高的就是 啊啊啊 还有

当然哈,这个 也有可能是说 MV 当中那台骚气十足的粉色的老爷车。

还有一个出现频率比较高的是 爷青回 ,我估计这个意思应该是 爷的青春回来啦 ,确实,周董伴随着我这个年龄段的人一路走来,做为一位 79 年的人现在已经是 41 岁的「高龄」了,回首往昔,让人唏嘘不已。

当年一首 「双节棍」 火遍了中华大地,大街上的音像店整天都在循环这几首歌,在学校上学的我这一代人,基本上是人人都能哼两句,「快使用双截棍,哼哼哈嘿」成了我们这一代人共有的回忆。

智能情感倾向分析

我们还可以对弹幕进行一次情感倾向分析,这里我使用的是 「百度 AI 开放平台」 的情感倾向分析接口。

百度 AI 开放平台文档地址:https://ai.baidu.com/ai-doc/NLP/zk6z52hds

首先是根据文档接入 「百度 AI 开放平台」 ,获取 access_token ,代码如下:

# 获取 Baidu API access_token
access_token_url = f'https://aip.baidubce.com/oauth/2.0/token?grant_type={grant_type}&client_id={client_id}&client_secret={client_secret}&' res = requests.post(access_token_url) access_token = res.json()['access_token'] # 通用情感接口
# sentiment_url = f'https://aip.baidubce.com/rpc/2.0/nlp/v1/sentiment_classify?charset=UTF-8&access_token={access_token}'
# 定制化情感接口
sentiment_url = f'https://aip.baidubce.com/rpc/2.0/nlp/v1/sentiment_classify_custom?charset=UTF-8&access_token={access_token}'

百度 AI 开放平台有两个情感分析接口,一个是通用的,还有一个是定制化的,我这里使用的是经过训练的定制化的接口,如果没有定制化的接口,使用通用的接口也没有问题。

上面使用到的 grant_typeclient_idclient_secret 这几个参数,大家注册一下就能得到, 「百度 AI 开放平台」 上的这些接口都有调用数量的限制,不过我们自己使用已经足够了。

然后读取我们刚才保存的弹幕文本:

with open("dan_mu.txt", encoding="utf-8") as f:
txt = f.read()
danmu_cat = txt.split("\n")

在调用接口获得情感倾向之前,我们还需要做一件事情,对弹幕进行一次处理,因为弹幕中会有一些 emoji 表情,而 emoji 直接请求百度的接口会返回错误,这里我使用另一个工具包对 emoji 表情进行处理。

首先安装工具包 emoji :

pip install emoji

使用是非常简单的,我们对弹幕数据使用 emoji 进行一次处理:

import emoji

with open("dan_mu.txt", encoding="utf-8") as f:
txt = f.read()
danmu_list = txt.split("\n") for item in danmu_list:
print(emoji.demojize(item))

我们的弹幕数据中是有这样的 emoji 表情的:



# 处理后:
:red_heart::red_heart::red_heart::red_heart::red_heart::red_heart::red_heart:

然后,我们就可以调用百度的情感倾向分析接口,对我们的弹幕数据进行分析了:

# 情感计数器
optimistic = 0
neutral = 0
pessimistic = 0 for danmu in danmu_list:
# 因调用 QPS 限制,每次调用间隔 0.5s
time.sleep(0.5)
req_data = {
'text': emoji.demojize(danmu)
}
# 调用情感倾向分析接口
if len(danmu) > 0:
r = requests.post(sentiment_url, json = req_data)
print(r.json())
for item in r.json()['items']:
if item['sentiment'] == 2:
# 正向情感
optimistic += 1
if item['sentiment'] == 1:
# 中性情感
neutral += 1
if item['sentiment'] == 0:
# 负向情感
pessimistic += 1 print('正向情感:', optimistic)
print('中性情感:', neutral)
print('负向情感:', pessimistic) attr = ['正向情感','中性情感','负向情感']
value = [optimistic, neutral, pessimistic] c = (
Pie()
.add("", [list(attr) for attr in zip(attr, value)])
.set_global_opts(title_opts=opts.TitleOpts(title="「MOJITO」弹幕情感分析"))
.render("pie_base.html")
)

最后的结果图长这样:

从最后的结果上来看,正向情感占比大约在 2/3 左右,而负向情感只有不到 1/4 ,看来大多数人看到周董的新歌还是满怀激动的心情。

不过这个数据不一定准确,最多可以做一个参考。

源代码

需要源代码的同学可以在公众号后台回复「MOJITO」获取。

MOJITO 发布一周,爬一波弹幕分析下的更多相关文章

  1. 以“有匪”为实战案例,用python爬取视频弹幕

    最近腾讯独播热剧"有匪"特别火,我也一直在追剧,每次看剧的时候都是把弹幕开启的,这样子看剧才有灵魂呀.借助手中的技术,想爬取弹幕分析下这部电视剧的具体情况和网友们的评论!对于弹幕的 ...

  2. .NET斗鱼直播弹幕客户端(下)

    .NET斗鱼直播弹幕客户端(下) 在上篇文章中,我们提到了如何使用.NET连接斗鱼TV直播弹幕的基本操作.然而想要做得好,做得容易扩展,就需要做进一步的代码整理. 本文将涉及以下内容: 介绍如何使用R ...

  3. Linux内核设计第五周——扒开系统调用三层皮(下)

    Linux内核设计第五周 ——扒开系统调用三层皮(下) 一.知识点总结 1.给MenuOS增加新的命令的步骤 更新menu代码到最新版 test.c中main函数里,增加MenuConfig() 增加 ...

  4. Linux内核分析第三周学习博客——跟踪分析Linux内核的启动过程

    Linux内核分析第三周学习博客--跟踪分析Linux内核的启动过程 实验过程截图: 过程分析: 在Linux内核的启动过程中,一共经历了start_kernel,rest_init,kernel_t ...

  5. 安居客scrapy房产信息爬取到数据可视化(下)-可视化代码

    接上篇:安居客scrapy房产信息爬取到数据可视化(下)-可视化代码,可视化的实现~ 先看看保存的数据吧~ 本人之前都是习惯把爬到的数据保存到本地json文件, 这次保存到数据库后发现使用mongod ...

  6. 一个简单的爬取b站up下所有视频的所有评论信息的爬虫

    心血来潮搞了一个简单的爬虫,主要是想知道某个人的b站账号,但是你知道,b站在搜索一个用户时,如果这个用户没有投过稿,是搜不到的,,,这时就只能想方法搞到对方的mid,,就是 space.bilibil ...

  7. 用Python分析下王小波与李银河写情书最爱用哪些词

    作家王小波其实也是我国最早期的程序员,突发奇想,王小波写情书最喜欢用哪些词呢?用Python词云分析下! 直接上代码吧,有注释很好理解.输出的图片设置的比较大,所以运行的比较慢,可以适当把图片尺寸改小 ...

  8. python爬取B站视频弹幕分析并制作词云

    1.分析网页 视频地址: www.bilibili.com/video/BV19E… 本身博主同时也是一名up主,虽然已经断更好久了,但是不妨碍我爬取弹幕信息来分析呀. 这次我选取的是自己 唯一的爆款 ...

  9. 个人永久性免费-Excel催化剂功能第72波-序列规则下的数据验证有效性好帮手:快速录入窗体辅助录入

    Excel作为最好用的数据录入工具,没有之一,如果能够充分利用好Excel的灵活性和规范性,将带来极大的生产力提升,前面的几波功能也有做了几大数据录入的辅助功能,今天再次给大家带来一个特定的使用场景, ...

随机推荐

  1. 查看包名和Activity的小工具

    添加到右键菜单,很方便. 做个记录:请移步原文

  2. JavaSE案例-Bank

    项目介绍 完成基本的银行业务功能 存款 取款 转账 查询余额 修改密码 修改预留手机号 注销账号 退出 任务分解: 定义三个基本类: BankTest():银行业务主程序 Bank(): 银行类,包含 ...

  3. NetCore项目实战篇08---Docker挂载mysql并连接.netCoreWeb

    我们的项目之前在直接连接的mysql,今天我们将通过docker挂载mysql 并与我们开发的webapi项目连接. 1. 安装docker 下载地址: https://download.docker ...

  4. golang内置类型和内置函数

    golang内置类型和内置函数是不需要引入包直接可用的 golang内置类型: 数值类型 string int,unint float32,float64 bool array 有长度的 comple ...

  5. 【Tomcat】JSP使用Session、Cookie实现购物车

    购物界面shop.jsp 初始页面 添加商品后,在session中设置属性,重定向回到shop.jsp,然后根据session的内容显示结果 Cookie设置setMaxAge可以延长session的 ...

  6. java方法句柄-----5.Method Handles in Java

    Method Handles in Java 目录 Method Handles in Java 1.介绍 2.什么是MethodHandle 3. Method Handles vs Reflect ...

  7. MySQL 高级—— 锁机制

    个人博客网:https://wushaopei.github.io/    (你想要这里多有) 一.锁的概述 1.锁的定义 锁是计算机协调多个进程或线程并发访问某一资源的机制. 在数据库中,除传统的计 ...

  8. 结合 AOP 轻松处理事件发布处理日志

    结合 AOP 轻松处理事件发布处理日志 Intro 前段时间,实现了 EventBus 以及 EventQueue 基于 Event 的事件处理,但是没有做日志(EventLog)相关的部分,原本想增 ...

  9. SchedTune

    本文仅是对kernel中的document进行翻译,便于理解.后续再添加代码分析. 1. 为何引入schedtune? schedutil是一个基于利用率驱动的cpu频率governor.它允许调度器 ...

  10. Java实现 LeetCode 789 逃脱阻碍者(曼哈顿距离)

    789. 逃脱阻碍者 你在进行一个简化版的吃豆人游戏.你从 (0, 0) 点开始出发,你的目的地是 (target[0], target[1]) .地图上有一些阻碍者,第 i 个阻碍者从 (ghost ...