《阿凡达·水之道》于2022年12月16日上映。第一部的口碑、评分等都非常高,第二部是否能延续呢,本文获取了该电影的豆瓣短评,进行了初步的分析,看下观众都是如何评价的。
数据获取
打开豆瓣首页,搜索电影名,进入《阿凡达·水之道》的详情页。
然后向下滚动页面,找到豆瓣短评。
点击全部短评进入评论详情页面,每一页有20条评论。按F12,鼠标前后翻页抓取网页请求信息。
根据网页信息可以得到请求方式为GET,同时获取到Request URL,Request Headers,Cookies。有了这些信息,就可以写代码爬取短评内容了。
代码中使用requests库向豆瓣发送GET请求,一次请求可以获取一页评论数据,改变URL中的start,循环多次发送请求,即可获取所有的评论数据。
网页爬取成功后,用正则表达式匹配需要用到的数据,依次写到excel中。
本文共获取到了580条评论,豆瓣会优先把点赞(有用)数高的评论排在前面,这580条评论是相对点赞更多的,能满足本文的分析。
评论用户是否看过电影
def is_all_seen():
"""判断是否所有用户都看过"""
df = pd.read_excel('afanda_water_sort_comments.xlsx')
seen = df['是否看过']
seen.value_counts().plot.pie(figsize=(5, 2.4), ylabel='', autopct='%.2f%%', colors=['c', 'b'],
textprops={'fontsize': 12, 'color': 'b'}, pctdistance=1.3, labeldistance=1.8)
plt.show()
在580条评论中,只有个别用户没有看过电影,基本都是看过电影后发表的评论。
评论用户的打星分布
def star_distribution():
"""星级分布"""
df = pd.read_excel('afanda_water_sort_comments.xlsx')
star = df['星级']
four, five, three, two, one, zero = star.value_counts(dropna=False)
star_num = {'0星': zero, '1星': one, '2星': two, '3星': three, '4星': four, '5星': five}
fig = pd.Series(star_num).plot.barh(figsize=(5, 3), color='#FF9900', width=0.7)
for a, b in zip(range(len(star_num)), star_num.values()):
plt.text(b+2, a, '%.0f' % b, ha='left', va='center')
plt.xticks(range(0, 300, 50))
x_ticks = fig.xaxis.get_major_ticks()
for i in range(len(x_ticks)):
x_ticks[i].set_visible(False)
for spine in fig.spines:
fig.spines[spine].set_visible(False)
fig.tick_params(bottom=False, top=False, left=False, right=False)
plt.show()
从评分来看,大部分评分在3星至5星,其中最多的是4星。
评论内容词云图
def gen_word_cloud():
"""生成词云图"""
df = pd.read_excel('afanda_water_sort_comments.xlsx')
comment = df['评论内容']
for i in range(500):
with open('comment.txt', 'a', encoding='utf-8') as f:
f.write(comment[i])
with open('comment.txt', 'r', encoding='utf-8') as f:
all_comment = f.read()
cut_text = jieba.cut(all_comment)
result = ' '.join(cut_text)
exclude = {'的', '了', '是', '在', '有', '我', '和', '也', '都', '但'}
gen_stylecloud(
text=result, size=(800, 600), max_words=1000, max_font_size=100, font_path='simhei.ttf',
icon_name='fas fa-dragon', output_name='afanda_water_comment.png',
background_color='#05243F', custom_stopwords=exclude,
)
评论的热词主要有电影名阿凡达,电影的背景设定潘多拉星球、海底世界,电影时长三个小时等,从热词中不能明显的看出大家的评论是好是坏。
评论点赞数分布
def likes_distribution():
"""评论点赞数分布"""
df = pd.read_excel('afanda_water_sort_comments.xlsx')
likes = df['赞同数']
likes_division = {
'少于100': len(likes[(0 <= likes) & (likes < 100)]),
'100至500': len(likes[(100 <= likes) & (likes < 500)]),
'超过500': len(likes[500 <= likes])
}
explode = (0, 0.05, 0.1)
pd.Series(likes_division).plot.pie(figsize=(5, 3), ylabel='', autopct='%.0f%%', pctdistance=0.85,
colors=['c', 'b', '#FF9900'], explode=explode, startangle=7.5, textprops={'fontsize': 14, 'color': 'm'})
plt.pie([i for i in likes_division.values()], radius=0.7, colors='w', explode=explode, startangle=7.5)
plt.pie([1], radius=0.7, colors='w')
plt.show()
评论的点赞整体并不高,点赞超过500的评论只有3%,超过100的也只有8%。
热评的点赞数
def hot_comment_likes():
"""热评的点赞数"""
df = pd.read_excel('afanda_water_sort_comments.xlsx')
top_10_likes = df['赞同数'].sort_values(ascending=False).head(10)
fig = top_10_likes.plot.bar(figsize=(5, 3), color='#0099CC', width=0.7, )
for a, b in zip(range(len(top_10_likes)), top_10_likes):
plt.text(a, b+100, '%.0f' % b, ha='center', va='bottom')
plt.xticks(range(10), ['Hot{}'.format(i+1) for i in range(10)], rotation=0)
plt.yticks([])
fig.tick_params(axis='x', colors='#FF0033')
for spine in fig.spines:
fig.spines[spine].set_visible(False)
fig.tick_params(bottom=False, top=False, left=False, right=False)
plt.show()
点赞最高的评论获得了3千多次点赞,点赞数并不是很高,有可能跟电影上映时间不长、参与人数不多有关。
评论情感分析
def emotional_analysis():
df = pd.read_excel('afanda_water_sort_comments.xlsx')
df.fillna(0)
# 情感分析
print('【提示】正在进行情感分析中...')
df['情感分析转换'] = df['评论内容'].apply(lambda x: str(x))
df['情感分值'] = df['情感分析转换'].apply(lambda x: SnowNLP(x).sentiments)
print('情感分析完成\n{}'.format('*'*30))
# 情感分值分布
df['情感分值'].plot.hist(figsize=(8, 4), bins=10)
plt.xticks(ticks=[x/10 for x in range(11)], labels=[x/10 for x in range(11)])
plt.yticks(range(0, 500, 100))
plt.title('情感分值分布', fontsize=16)
plt.xlabel("情感分值", fontsize=14)
plt.ylabel('')
s = df['情感分值'].copy()
counts = [s[(i / 10 < s) & (s <= i / 10 + 0.1)].count() for i in range(10)]
for a, b in zip([x/10 for x in range(11)], counts):
plt.text(a+0.05, b+10, int(b), ha='center', va='center', fontsize=12)
plt.show()
# 情感分值积极和消极占比
pos_neg_count = pd.Series({
'消极倾向': s[(0 <= s) & (s <= 0.5)].count(),
'积极倾向': s[(0.5 < s) & (s < 1)].count()
})
pos_neg_count.plot.pie(figsize=(8, 4), ylabel='', autopct='%.02f%%', startangle=150)
plt.show()
情感分析是指通过文本来挖掘人们对于产品、服务、组织、个人、事件等的观点、情感倾向、态度等。根据不同文本内容的语义,每个词有不同的情感倾向,情感分析对不同的文本进行分析后返回对应的情感分值,情感分值在0到1之间,值越大表示倾向越积极。
本文对评论内容进行分析后,发现情感分值分布最多的区间是0.9-1,远高于其他区间,最积极的评论内容占比最多。
将情感分值小于等于0.5定义为消极倾向,情感分值大于0.5定义为积极倾向,积极倾向占了近8成,整体的评价是非常积极的。
从情感分析结果来看,大家的评论还不错。不过情感分析也有一定的局限性,仅供参考。从我个人的角度评论,我觉得一般。