背景
小丑社的经费都去哪了
故事要追溯到2018年年底,当时正值《东京喰种:re》最终季的放映。
我是在那年暑假才开始一口气从第一季一直看到第三季结束,然后追上进度的,和许多观众一样,期待着第四季能够重现第一季最后一集的打戏:
然后很快就到了第四季开播的时候。清楚地记得在那一天晚上,我穿过瑟瑟秋风回到宿舍,打开电脑,迫不及待地点进了刚更新的第二集,接下来就看到了这个:
这个:
和这个:
在那一集播出后,贴吧里也充满了各种不满的声音,评分也急速下滑。而到了后面几集也是如此,ppt场面不断,几乎只要一有打戏,就会全程透露出一股贫穷的气息。当时在贴吧看到过这样一句话:
那个时候虽然没看过火影,但或多或少知道原作在几年前刚刚完结,现在正在更新续作《博人传》,于是就好奇去b站搜了一下。结果这不看不知道,一看吓一跳:这评分,比喰种还要低……
“可燃”?“不可燃”?
因为当时还没看过疾风传,所以就没有进一步探究这个“奇怪”的现象。直到大三疫情期间的时候,才在家从头开始刷火影,一直刷到快要毕业的时候才看完。整个过程下来看的是非常的爽,完全想象不出来这和喰种第四季是同一个公司负责的。
看完原作720集后,自然是想试一试《博人传》这个续作。尽管此时续作评分已经掉到了4.2分,之前也有不少同学来劝退过,但我还是想亲自尝试一下主线部分(其中一个原因是看到最新的短评有一大半都是给的五星,基本上说的都是不可燃物终于燃起来了)。于是我就照着b站热门评论区的路线,把200来集中的为数不多的主线剧情和推荐剧情刷了一遍。主观上来讲,观感虽然明显低于疾风传(具体内容放在最后再说),但也不至于像星战9(情怀都不知道怎么卖,ppt莫名诈尸随后又被击杀,天行者家族都断了还叫天行者崛起)或刀剑uw终章(心理活动全删,经费几乎全用在观众不想看的地方,像是黑粉进了制作组)这么差。
为什么在最近大多数评价都是五星的情况下,评分仍然会在4.2分维持数月?为什么最近一年来,“比博燃”这个梗能够迅速火出圈(火到即便最近几十集的质量都明显好了很多,“比博燃”弹幕也还是不断地出现在b站中的各个视频)?这中间究竟是哪些地方得罪了这么多观众,导致出现了即便是大半年的五星都救不起来的评分?本人非常好奇,便决定通过爬取b站的弹幕数、播放数、点赞量、短评等数据,来对《博人传》迄今为止的200来集进行一个多方面的口碑分析。
技术实现及主要思路
由于对爬虫技术基本不了解,本次代码依旧使用易于入手的python进行编写。在这里爬取网站主要使用requests和bs4这两个模块,前者用于获取response,后者用于获取response中的json文本。
本节将会主要展示获取各种数据信息的方式,以及在处理数据时的一些基本假设和思路。
b站番剧的几个重要标识
在b站,每部番剧都对应着一个id:media_id(也有些时候叫season_id,具体区别不太清楚,但就目前情况而言,它们都是一样的),这个id可以在f12模式下的NetWork >> Fetch/XHR中找到:
而每个番剧自然而然地,又或多或少地包含多个集数,这些集数是用ep_id进行标识的,这个值在播放相应剧集时就可以从网址中看出来(ep后面跟着的几个数字就是ep_id):
一般情况下,有了media_id和ep_id,就可以获取每一集的各个参数了。
各集ep_id的获取
还有一个问题就是,如何在已知media_id的情况下,查询对应的ep_id?此前我曾经在f12中试了试,但却始终没有找到查询ep_id列表的那个请求。因此,在本次ep_id的获取中,我采用的是非常笨的手动复制的方法(即一边拖动选集的进度条,一边在html代码中复制动态加载出来的新集数的那些链接。一次最多能同时显示40集的信息,所以总共也没有花多长时间)。
而几天后在网上搜索相关资料时,则在一篇文章【1】中发现了通过media_id获取ep_id列表的URL:
https://api.bilibili.com/pgc/web/season/section?season_id=
在最后那里补上对应的season_id值,就可以看到相应的每一集的信息了:
可惜这个时候已经用手动的方式提取完了,所以就没有再用到这个URL了。
提取后的结果,简单地放在了一个txt文本文档里,此后使用numpy这样的模块可以很方便地对其进行读取:

各集播放量、点赞量、硬币和弹幕数的获取
有了每一集的ep_id,就可以利用这个id,去获取单集的各种数据了。首先在网页中使用f12,继续查看NetWork >> Fetch/XHR,点开其中的info?ep_id=396076,在Headers中找到Request URL:https://api.bilibili.com/pgc/season/episode/web/info?ep_id=396076:
点开Preview,可以在里面看到该集的统计(stat)信息,其中就包括了硬币、弹幕、点赞、评论和播放量这五个数据。因此可以断定,在这个链接里面有我们想要的:
在网页中打开这个链接,可以看到这些返回的信息的原始json文本:
因此接下来,只要让程序逐ep_id来访问各自对应的url,并从中获取json文本,将其转为json格式,再从里面拿出想要的数据就可以了。
相应程序
import requests
from bs4 import BeautifulSoup
import json
import csv
from time import sleep
import random
import numpy as np
csvfile = open('data.csv', 'w', newline='')
spamwriter = csv.writer(csvfile, delimiter=' ',
quotechar='|', quoting=csv.QUOTE_MINIMAL)
epIdList = np.loadtxt("epIdList.txt")
for i in epIdList:
URL = "https://api.bilibili.com/pgc/season/episode/web/info?ep_id=%d" % i
try:
rsp = requests.get(URL)
soup = BeautifulSoup(rsp.text, 'html.parser')
episodeInfo = soup.get_text()
parsedEpisodeInfo = json.loads(episodeInfo)
coinNum = parsedEpisodeInfo['data']['stat']['coin']
likeNum = parsedEpisodeInfo['data']['stat']['like']
commentNum = parsedEpisodeInfo['data']['stat']['reply']
viewNum = parsedEpisodeInfo['data']['stat']['view']
dmNum = parsedEpisodeInfo['data']['stat']['dm']
spamwriter.writerow([viewNum, dmNum, likeNum, coinNum, commentNum])
print("finished: episode %d" % (i + 1))
except:
print("episode %d: %s error" % (i + 1, URL))
sleepTime = random.random()
sleep(sleepTime)
csvfile.close()
在运行这个程序后,所有的数据都会被写入到csv文件中,以方便后续分析的进行:

短评评分信息的获取
另外一个想要分析的是单集评分,以及总评随时间的变化,这就需要将评分区中的每条评论的分数和评论时间记录下来。最开始自己找到的链接有一个cursor参数,对其百思不得其解,总是搞出各种死循环,于是就上网搜集大佬们的方法【2】,采用了另外一类链接:
https://bangumi.bilibili.com/review/web_api/short/list?media_id=5978&folded=0&page_size=20&sort=0
在这个链接中,每一页的最后一条评论里,都会有一个名为cursor的参数,将其值以"&cursor=xxx"的形式附加在这个链接的最后面,就可以正确地跳转到下一页。以此类推,这样就可以获得全部的短评信息。
而关于长评,本人比较懒,就没有单独获取了。
相应程序
import requests
from bs4 import BeautifulSoup
import json
import time
import random
import csv
import traceback
def ingestCommentInfoAndWrite(commentInfo, spamwriter):
commentList = commentInfo['result']['list']
for eachComment in commentList:
content = eachComment['content']
ctime = eachComment['ctime']
likes = eachComment['likes']
mtime = eachComment['mtime']
score = eachComment['user_rating']['score']
spamwriter.writerow([ctime, score, content, likes, mtime])
urlTemplete = "https://bangumi.bilibili.com/review/web_api/short/list?media_id=5978&folded=0&page_size=20&sort=0"
url = urlTemplete
i = 1
count = 0
total = 105959
csvfile = open('commentInfo.csv', 'a', newline='', encoding='utf-8-sig')
spamwriter = csv.writer(csvfile, delimiter=',',
quotechar='|', quoting=csv.QUOTE_MINIMAL)
while True:
try:
rsp = requests.get(url)
soup = BeautifulSoup(rsp.text, 'html.parser')
commentInfo = soup.get_text()
commentInfo = json.loads(commentInfo)
nextCursor = commentInfo['result']['list'][-1]['cursor']
ingestCommentInfoAndWrite(commentInfo, spamwriter)
print("[%d] %s: finish %d/%d" % (i, url, count, total))
count += len(commentInfo['result']['list'])
if(count >= total):
break
url = urlTemplete + "&cursor=%s" % nextCursor
i += 1
failed = 0
except:
traceback.print_exc()
print("[%d] %s: error" % (i, url))
failed += 1
if(failed >= 10):
break
csvfile.close()
这里有一处失误:在初始化spamwriter的时候,设置了quotechar=’|’,这样一来评论中所有的’|'都会成为单元格之间的分界符。因此,在最后得到的csv文件中,从十万条评论中删除了两百来条因为这个原因破坏了列数格式的数据。最后得到的csv,对列进行了调整后的大致情况如下:
其中,第一列是mtime,第二列是评分,第三列是评论具体内容,第四列是评论获赞数,第五列是ctime。
经过后续的尝试,推测mtime和ctime区别在于:前者是最后修改评论的时间,后者则是第一次发表评论的时间。由此看来,分析数据时,采用mtime而非ctime比较合理(因为只能获取修改后的评分)。
这里的时间使用的是时间戳格式,而接下来要获取的番剧发布时间也是时间戳格式。因此在这里得到的时间无需转换格式即可直接使用。
各集发布时间的获取
因为主要想看的是单集评分,所以就需要将评论时间转换为具体对应的集数。因此,首先就需要知道每一集都是什么时候发布的。
关于这个发布时间,我到f12、必应找遍好多地方都没有看到一点相关的信息。直到我点开了TV-TOKYO(放映《博人传》的东京电视台在b站的账号)的个人主页后,才发现:
每当新的一集在b站上显示的时候,这个个人主页也会随之更新!
这样一来,整个过程就变得很容易了:只要找出这个用户的视频列表所对应的json文本链接,就可以获取每一集的发布时间了。经过一番并不困难的寻找,链接找到了:
https://api.bilibili.com/x/space/arc/search?mid=21453565&ps=30&tid=0&pn={pn}&keyword=&order=pubdate&jsonp=jsonp
只要不断地切换pn的值,就可以逐个地读取每个页面的视频列表。只要将名字含有"博人传"的那些信息全部提取出来,并同时从标题中获取集数编号,就可以达到目的了。
相应程序
from bs4 import BeautifulSoup
import requests
import csv
import json
import re
import traceback
def write2csv(eachVideoInfo, spamwriter):
episodeNum = re.search("(\d+)$", eachVideoInfo['title']).group(1)
createTime = eachVideoInfo['created']
spamwriter.writerow([episodeNum, createTime])
url_before = "https://api.bilibili.com/x/space/arc/search?mid=21453565&ps=30&tid=0&pn="
url_after = "&keyword=&order=pubdate&jsonp=jsonp"
csvfile = open('episodeInfo.csv', 'w', newline='')
spamwriter = csv.writer(csvfile, delimiter=',',
quoting=csv.QUOTE_MINIMAL)
for pn in range(1, 81):
url = url_before + "%s" % pn + url_after
try:
rsp = requests.get(url)
soup = BeautifulSoup(rsp.text, 'html.parser')
videoInfoPage = soup.get_text()
videoInfoPage = json.loads(videoInfoPage)
videoInfoList = videoInfoPage['data']['list']['vlist']
for eachVideoInfo in videoInfoList:
if (re.search(".*博人传.*", eachVideoInfo['title'])):
write2csv(eachVideoInfo, spamwriter)
print("pn %s: finish" % pn)
except:
traceback.print_exc()
print("pn %s: error" % pn)
csvfile.close()
这里预先看了一下,当前第一集排在了70多页,所以就只抓取80页的信息(如果要使通用性更强的话,应该设置一个超出最大页数范围时的自动退出)。
运行后,每一集的发布时间信息也被写在了csv文件中:
为了方便将每个评论的时间戳映射到对应的集数,一个比较简单的方法是建立一个数据库,指定每一集的时间戳范围。将第i集的起始时间设定为自己的发布时间,而终止时间设定为第i+1的发布时间;如果是最新的一集,则将终止时间设置为当前时间的一天后:
import sqlite3
import numpy as np
import time
conn = sqlite3.connect("data.db")
D = np.loadtxt("episodeInfo.csv", delimiter=',')
for idx in range(len(D)):
episode_num = D[idx, 0]
start_tp = D[idx, 1]
if(idx == len(D) - 1):
end_tp = time.time() + 86400 # 在当前时间的基础上,加上一天
else:
end_tp = D[idx+1, 1]
c = conn.cursor()
c.execute("insert into episodeInfo values(%s, %s, %s)" % (episode_num, start_tp, end_tp))
conn.commit()
conn.close()
此后,如果要将各个评论的时间映射到相应的集数的话,可以利用如下sql语句:
"select episode_num from episodeInfo where start_tp <= %s and %s < end_tp" % (mtime, mtime)
返回的结果就是映射到的那个集数。
评分对应集数的修正
在前面的几个步骤中,已经将评论的时间顺利地转化为对应的集数了。这样算出来的单集评分对应的情况是:在每一集发布后,到下一集发布前的这段时间,所有的评分都是只针对这一集的。这样的情况显然不合理,因此需要进行一些修正。
为了方便讨论,首先设各集评分人数向量:
n → = ( n 1 , n 2 , … , n m ) \begin{aligned}\overrightarrow n=(n_1,\ n_2,\ \dots,\ n_m)\end{aligned} n=(n1, n2, …, nm)
和各集评分总和向量:
s → = ( s 1 , s 2 , … , s m ) \begin{aligned}\overrightarrow s=(s_1,\ s_2,\ \dots,\ s_m)\end{aligned} s=(s1, s2, …, sm)
其中, m m m是总集数,向量中的第 i i i个元素表示第 i i i集对应的数据。
显而易见, s → \overrightarrow s s对 n → \overrightarrow n n进行一次按元素除法,即可得到最终的各集得分向量。
现在的目标,就是对这两个向量进行修正,自然而然地想到使用矩阵。
评分转移矩阵
现在构造一个 m × m m\times m m×m的矩阵 M M M,令第 i j ij ij元素表示在第 i i i集中评分的人,有多大的一部分是去评论第 j j j集的。经过验证,为了使上述说法成立,只需要将 M M M右乘在 n → \overrightarrow n n或 s → \overrightarrow s s上即可。例如,在未修正的情况下, M = I M=I M=I,则此时代表的情况是,每一集新发布期间的评论都是针对这一集的。
根据上述的说法,因为观众不能给还未上映的剧集打分,所以 M i j = 0 , j > i M_{ij}=0,\ j>i Mij=0, j>i。
在这里,简单假设观众在打分时,有80%是针对当前的这一集,10%是针对上一集,5%针对上两集,3%针对上三集,2%针对上四集(在前面的集数不到五集时,则需要单独假设),则矩阵可以构造为:
M = ( 1 0 0 0 0 0 ⋯ 0 0.2 0.8 0 0 0 0 ⋯ 0 0.05 0.15 0.8 0 0 0 ⋯ 0 0.03 0.07 0.1 0.8 0 0 ⋯ 0 0.02 0.03 0.05 0.1 0.8 0 ⋯ 0 0 0.02 0.03 0.05 0.1 0.8 ⋯ 0 ⋮ ⋮ ⋮ ⋮ ⋮ ⋮ ⋮ 0 0 0 0 0 0 ⋯ 0.8 ) M = \left(\begin{matrix}1 & 0 & 0 & 0 & 0& 0 & \cdots & 0\\ 0.2 & 0.8 & 0 & 0 & 0 & 0 & \cdots & 0\\ 0.05 & 0.15 & 0.8 & 0 & 0 & 0 & \cdots & 0\\ 0.03 & 0.07 & 0.1 & 0.8 & 0 & 0 & \cdots & 0\\ 0.02 & 0.03 & 0.05 & 0.1 & 0.8 & 0 & \cdots & 0\\ 0 & 0.02 & 0.03 & 0.05 & 0.1 & 0.8 & \cdots & 0\\ \vdots & \vdots & \vdots & \vdots & \vdots & \vdots & & \vdots\\ 0 & 0 & 0 & 0 & 0 & 0 & \cdots & 0.8\end{matrix}\right) M=⎝⎜⎜⎜⎜⎜⎜⎜⎜⎜⎜⎜⎛10.20.050.030.020⋮000.80.150.070.030.02⋮0000.80.10.050.03⋮00000.80.10.05⋮000000.80.1⋮0000000.8⋮0⋯⋯⋯⋯⋯⋯⋯000000⋮0.8⎠⎟⎟⎟⎟⎟⎟⎟⎟⎟⎟⎟⎞
用这个矩阵对原有的两个向量进行修正:
s ′ → = s → M , n ′ → = n → M \overrightarrow {s'}=\overrightarrow sM,\ \overrightarrow {n'}=\overrightarrow nM s′=sM, n′=nM
然后再让前者对后者进行按元素除法,即可得到修正后的单集评分向量。
相应程序
import numpy as np
import numpy.matlib
import sqlite3
import csv
totalNumber = 201 # 当前集数
# 初始化评分总人数,评分总和向量
totalPeopleVector = np.matlib.zeros((1,totalNumber))
sumScoreVector = np.matlib.zeros((1,totalNumber))
# 构造分数转移矩阵
M_sub1 = numpy.matlib.eye(n = totalNumber, k = 0, dtype = float) * 0.8
M_sub2 = numpy.matlib.eye(n = totalNumber, k = -1, dtype = float) * 0.1
M_sub3 = numpy.matlib.eye(n = totalNumber, k = -2, dtype = float) * 0.05
M_sub4 = numpy.matlib.eye(n = totalNumber, k = -3, dtype = float) * 0.03
M_sub5 = numpy.matlib.eye(n = totalNumber, k = -4, dtype = float) * 0.02
M = M_sub1 + M_sub2 + M_sub3 + M_sub4 + M_sub5
M[0,0] = 1
M[1,0] = 0.2
M[2,1] = 0.15
M[3,1] = 0.07
print("矩阵初始化完毕!")
# 连接到数据库
conn = sqlite3.connect("data.db")
# 读取评论信息
commentData = np.loadtxt("commentInfo.csv", delimiter=',', dtype = str, encoding='utf-8-sig')
for eachComment in commentData:
mtime = int(eachComment[0])
score = int(eachComment[1])
c = conn.cursor()
cursor = c.execute("select episode_num from episodeInfo where start_tp <= %s and %s < end_tp" % (mtime, mtime))
episode_num = cursor.fetchone()[0]
totalPeopleVector[0,episode_num-1] += 1
sumScoreVector[0,episode_num-1] += score
print("评论数据读取完毕!")
# 矩阵相乘
finalTotalPeopleVector = np.matmul(totalPeopleVector, M)
finalSumScoreVector = np.matmul(sumScoreVector, M)
finalScorePerEpisode = finalSumScoreVector / finalTotalPeopleVector
orgScorePerEpisode = sumScoreVector / totalPeopleVector
print("矩阵运算完毕!")
# 将结果写出到csv文件
csvFile = open("scoreEachEpisode.csv", "w", newline='')
spamwriter = csv.writer(csvFile, delimiter=',',
quotechar='|', quoting=csv.QUOTE_MINIMAL)
for idx in range(totalNumber):
spamwriter.writerow([idx+1, totalPeopleVector[0,idx], orgScorePerEpisode[0,idx], finalTotalPeopleVector[0,idx], finalScorePerEpisode[0,idx]])
csvFile.close()
print("文件写出完毕!")
# 断开与数据库的链接
conn.close()
矩阵运算的过程出乎意料的快,拖时间的反而是读取十万条评论的过程。
得到的最终数据文件如下:
文件中的第一列是集数,第二、三列分别是修正前的评分人数和均分,第四、五列则分别是修正后的评分人数和均分。
不知道是因为什么原因,短评最早只能看到第25集发布后的时期,前面的只能置nan处理。
至此,已经得到了所有待分析的数据,接下来就可以按照个人兴趣来处理了。
数据处理结果
单集播放信息变化
从这里可以较为直观地看出,目前最受欢迎的分别是65集(国人作画,全系列最佳回),175集和189集。而从193集起,国内因版权原因而滞后更新数月,从而导致了播放量的下滑(一直跟着进度看的基本上都去其他地方看慕留人传【台版翻译】了),这属于异常状况,故不应简单下结论。
其实与疾风传在b站上线的最后几十集(b站只有最后几十集)相比,博人传的播放量等数据其实也并没有低到“凉凉”的地步(当然,这也是因为疾风传前面600多集很多更精彩的没放上来):
单集相对播放量信息变化
从这里就可以更直观地看出,从壳始动篇的后期开始,点赞量/播放量的值就开始急剧飙升。结合前面的图来看,可以看出点赞量确实是翻了一番,且这是基于播放量不怎么变化的情况的。说明从这一篇章开始,大家对制作的满意度整体提升了不少,因此有了“博终燃”的说法。
值得注意的是,65集在其他方面都是显著的一个峰,但在点赞量/播放量这个方面来看却和其他集没有任何区别,这可能是因为当时大家都在忙着吹爆,忘了点赞(误)。
而从硬币/播放量这里来看,可以发现186集也是好评较多的一集(博人VS青,可惜木叶丸又倒了……)。
单集加权满意度变化
假定一个硬币顶两个赞,这样再来和赞加在一起进行分析,结果和前面的差不多,最受欢迎的集数分别为65集、129集,175集,186集和189集。
单集加权讨论热度变化
弹幕数与评论数的加权值相对于播放量的比值,从这里并不能看出多少有效信息(看起来更像是噪声图),只是发现134集左右讨论度很高,估计是被喷的最惨的“宇智波抱摔”那集。也许评分就是从那个时候开始,几乎被锁死在了低分段。
单集加权不满意度变化
这个其实可以当做“白嫖指数”来理解。而这张图看起来就很明显了,“白嫖指数”在不断地下滑,说明剧集质量在不断地提升。当然,这可能也和播放量的下滑有关。
单集评分状况
大致规律和猜想的一样,在140集前的日常原创时期,单集评分基本上是稳步下滑,偶尔在有一些亮点时才会昙花一现,到了主线剧情后才会开始迅速涨分。而到了140集后,即便是原创,也能在大多数的时间里保持一定的分数(不过这是从最底线慢慢地往上涨,涨了半天还是4-6分那样子……),主线则是隔三差五地爆出相对较高的分数。有趣的是,到了慕留人时期,分数几乎一直都能卡在7分出头,这也许是因为少了很多为黑而黑的评论者。
有趣的是,65集只有3000来人参与评分,而到了134集的时候,却有9000多人参与了评分!134集也是单集评分最低的一集,可见其对整个博人传的影响之大。
截止各集时期的累计评分
注:这里看的就是总评分的演化,故不需要对评分集数进行修正
从这里就能看得更明显了:前期没什么人发评论,分数慢慢下降。65集来了一大波短评,分数一阵猛抬,但此后的一大把原创使得分数以先慢后快的形势下滑(目测后面那个大滑坡可能和各up主吐槽的“别小瞧我!”【第120集】有关)。
而穿越篇前几集让大家感到极其舒适,短评数量飚增,眼看评分又要开始暴涨。没想到后面几集又来了欠费打斗+各种迷惑操作这么一出,这使得被前几集吸引来的大量观众几乎都接受不了了,立即全员给出1星。也就是这个时候,累计评分人数几乎翻了一倍,大局几乎就是在这个时候定了。
此后从150集左右开始,虽然大家都评价观感好了不少,也有许多人在短评处重新开始打五星,但这个总评几乎就处于一种无力回天的状态了。后面新增短评的速度也显著高于100集前的速度,也许这里面就包含了大量被134集整的忍无可忍的观众以及部分跟风打分的用户,疯狂地在新的剧集里面继续刷一星。
当前的总分是4.2分,按目前这个状况看来,这个分数可能会在较长的一段时间内保持稳定不动了,多则慢慢地移向4.3、4.4,少则掉回4.1、4.0。
小结
从上述的情况来看,大家对主线剧情的认可度其实还算是可以的。本人也只看了主线和推荐剧集,体验一直都还算不错。但原创却是一个巨大的硬伤,动画组总会在原创中激怒几乎所有的观众,然后让大家一起来给1星,从而导致分数暴跌……
因为我没有看过博人传的原创(疾风传时期的原创除了无限月读和班出来前的那段之外基本都看过了),不能对其进行评价,所以就只能在这里简单地谈一下对主线的看法了:虽然主线在有些时候作画质量能够与疾风传持平甚至超过疾风传,但整体上来讲,还是比疾风传少了许多东西。
一个方面是情感渲染的丢失。在这一点上,和去年口碑崩盘的刀剑uw终章非常之像:很多时候,明明配上一点BGM,再让那个人加上几句独白,那不是挺好的吗?但动画制作组却总是避开这些。例如,动画组在原创剧情中花了一整集给麦野立flag,最后牺牲的时候却描写得异常草率。疾风传的时候,无论是阿斯玛还是自来也,在最后的时候都有大量的语言、神态、回忆或心理描写,配上BGM后更是能够让观众感到触动。再反过来看麦野牺牲的这段,只是喊了两句话就被掩埋了,上述的五个要素全都没有出现,自然让观众难以代入。再看几集后在临死时做回忍者的青,这就更草率了,一句话都没有,就给了个闭上眼睛的特写……当时镜头给到青的时候,我还以为是要让他回忆一下自己过去的作为,然后再配上各种独白的。结果?眼睛一睁一闭,就这?
另一方面是对反派的刻画实在是太过于平面了。疾风传时期,晓组织里的成员,或多或少都有自己故事与动机:长门受到了现实的打击,变得不相信和平的存在;鼬在团藏的逼迫下屠杀了全族人,不能再待在村里,随后再是去晓组织卧底……那么,博人传中的壳组织成员,都有什么故事?很遗憾,从目前动画的角度来看,基本上看着都挺像是纯粹的反派,甚至比飞段这样的角色还要无厘头数倍——飞段好歹还可以用自己的信仰来解释。目的是无限月读也就罢了,竟然还有种出神树就为了尝一口果实的味道怎么样的?
当然,值得赞赏的地方也是有的:博人传对主角团的刻画相比于反派而言就要好上不少。至少从主线的那几十集一路看过来,是可以实实在在地看出主角博人的成长的(完全不会想到要像在b站各种视频里面那样打来打去)。最近的这段剧情中,也花了不少的集数去对男二川木进行背景故事和人格的补充,不得不说这十几集是看着最舒服的剧集了。
打斗方面有时候还是挺燃的(例如65集火出圈的国人作画,175集压缩螺旋丸,189集体术肉搏,204集巅峰对决,207集千鸟),具体分析在前面提到了,这里就不详细叙述了。
总之,虽然在现在,《博人传》的评分非常地低,也有不少的各方面的问题,但在主线方面上却仍然有着不少可圈可点的地方。无论是从观感上,还是从数据上来说,《博人传》都不会是完全的“不可燃物”。希望此续集能够继承火之意志,以后继续燃下去……
参考链接
【1】作者:凡云。出处:bilibili。标题:2020年B站番剧相关API整合。链接:https://www.bilibili.com/read/cv5293665/
【2】作者:csdn业界要闻(转载)。出处:CSDN。标题:干货(附源代码) | 爬取一万条b站评论,分析9.7分的新番凭啥这么火?。链接:https://blog.csdn.net/CSDN_bang/article/details/83965548