查看原文
其他

《唐探3》做错了什么?|来自150万字影评的证据

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

本文作者:任   哲, 中南财经政法大学经济学院

本文编辑:王   彤

技术总编:戴   雯

爬虫俱乐部云端课程

  爬虫俱乐部于2020年暑期在线上举办的Stata与Python编程技术训练营和Stata数据分析法律与制度专题训练营已经圆满结束啦~应广大学员需求,我们的课程现已在腾讯课堂全面上线,且继续提供答疑服务。现在关注公众号并在朋友圈转发推文《来腾讯课堂学Stata和Python啦》或《8月Stata数据分析法律与制度专场来啦!》,即可获得600元课程优惠券,集赞50个再领200元课程优惠券!(截图发至本公众号后台领取)原价2400元的课程,现在只要1600元!
01

导读

本该去年春节档上映的《唐人街探案3》由于疫情原因推迟到了今年,宣传片中的密室、本格、黑帮、日本等元素加上Q的现身足足吊了影迷们一年的胃口。本以为多了一年时间进行后期打磨的《唐探3》,会为观众再次带来一场视觉盛宴,做好唐探宇宙承上启下的工作。可现实却是上映以来,《唐探3》票房喜人但口碑不断下滑。截至2月28日,《唐探3》豆瓣评分5.6分,远低于同期上映的《你好,李焕英》(8.1分),最终连票房都被反超(当然还是特别高)。
这个评分说实话让小编非常惊讶,因为在小编的印象之中,评分低于6分就是超级烂片的代名词。这部充满了日本元素,已经有两部前传打底,甚至有刘德华加入的《唐探3》,究竟做错了什么才能惹得这么多的差评,真是让人感到好奇,于是小编决定从其影评中寻找答案,说干就干,下面开始。02

影评爬取

关于豆瓣影评的获取,之前的推文已经有过详细介绍。主要分为两次爬虫:第一次爬虫需要找到目标影评所在网址,对该电影影评下的所有页面遍历,提取每位用户影评的标题与链接;第二次爬虫通过链接进行抓取,提取所需要的影评内容。具体操作过程,大家感兴趣的话可以前往推文《疫情下的家庭关系|《请回答1988》影评爬取》进行学习,这里不再赘述。本次爬虫小编爬取了《唐探3》最受欢迎的3000条影评,具体的代码如下:clear
cd d:/唐探3爬虫
******************************************
*豆瓣每页显示20条影评,所以3000条影评需要爬取150页
*一次爬虫抓取影评的标题、链接和评论时间
local p=150
set more off
forvalues i = 1/`p'{
  local j=(`i'-1)*20 //定义评论对应的数字编码
  di `j'
  cap copy"https://movie.douban.com/subject/27619748/reviews?start=`j'" temp.txt,replace
  infix strL v 1-100000 using temp.txt,clear

  preserve
  keep if index(v, `"<span content=""')
  replace v = ustrregexra(v,"<.*?>","") //利用正则表达式懒惰模式,把<>里的内容替换为空
  rename v time
  save time.dta ,replace
  restore

  keep if index(v,`"<h2><a href="')
  split v,p(`"""')
  rename v2 url
  split v3,p(">")
  split v32,p("<")
  rename v321 title
  keep url title

  merge using time
  drop _merge
  save "影评`i'.dta",replace //第i条评论对应的url、title保存为影评i.dta
    }
******************************************
*把上面生成的影评i.dta合并起来
clear
local files:dir "." file "影评*.dta"
foreach file in `files'{
append using "`file'" //把上面生成的影评i.dta合并起来
}
save 影评_all.dta ,replace
******************************************
*二次爬虫根据一次爬虫中获取的链接,爬取影评源代码
use "影评_all.dta",clear
gen v=""
set more off
forvalues i=1/`=_N'{
replace v=fileread(url) in `i' //把网页源代码拷贝到v中
while filereaderror(v[`i'])!=0 {
sleep `=int(runiform()*5000+5000)' //随机休息5-10秒
replace v=fileread(url) in `i'
}
sleep `=int(runiform()*5000+5000)' //随机休息5-10秒
}
save 影评源代码.dta,replace
执行完上述程序,就把所有需要的影评的源代码爬取下来了,注意爬取的时候不要贪快,太频繁的访问会影响豆瓣服务器正常工作从而使得ip被封哦。爬取到的结果如下:

变量v中就是影评所在网页的源代码,然后从源代码中提取电影评分score和评论content。具体操作步骤也可以参考《疫情下的家庭关系|《请回答1988》影评爬取》进学习,代码如下:*从影评源代码中提取评分和影评
use 影评源代码.dta,clear

*提取评分
gen score=ustrregexs(1) if ustrregexm(v,"allstar([0-9]{2})")
destring score,replace
replace score=score/10

*提取评论
split v,p(`"<div id="link-report">"' `"<div class="main-author">"')
replace v2 = ustrregexra(v2,"\s","",.)
replace v2 = ustrregexra(v2, "<.*?>", "",.)
replace v2=ustrregexra(v2,"&nbsp|-|;","")
rename v2 content

keep title score content
save 影评.dta ,replace
这样就得到了《唐探3》最受欢迎的3000条影评的评分和内容。如下图所示,可以发现在变量score中,有的评分为“.”,这是用户只写了影评但是没有打分,由于无法直观看出该用户的倾向,故在后续的分析之中我们要把这些影评删除。

03

影评分析

上文中得到了《唐探3》最受欢迎的3000条影评的评分和内容,其中本文将评分为4分和5分的视为好评,将3分视为中评,将1分和2分视为差评,并将尚未打分的影评视为无效影评删除。最终得到了有效影评2159条,好评519条,中评748条,差评892条。据此绘制饼图的代码和结果如下:use 影评.dta,replace
drop if score==. //删除无效影评

*将有效影评分类
gen 评价 = ""
replace 评价 = "好评" if score > 3
replace 评价 = "中评" if score == 3
replace 评价 = "差评" if score < 3

*绘制饼图
collapse (count) score,by(评价) //分组统计评分数量
egen total=sum(score) //计算评分的总数
gen fre=score/total
grstyle init //初始化图形设置
grstyle set plain //去掉图形背景色
graph pie fre ,over(评价) pie(5,explode color(navy *0.8)) plabel(_all percent ,size(*2) color(white))

可以看到有效影评中好评仅为24.04%,这对一个超级大IP来说实在是一个让人无法满意的成绩。接下来我们在Stata中调用Python来对影评的内容进行分词处理,并将秦风、唐仁等角色姓名和日本、推理等经常出现但无法体现影评特点的词加入停用词表之中,再利用分词结果绘制词云图。本文将分别绘制好评、中评和差评的词云图,并观察它们的异同。这里以绘制好评词云图的代码为例,展示如下:*分词处理
**好评
*导出为txt文档
use 影评.dta,clear
drop if score==. //删除无效影评
keep if score > 3 //只保留好评
keep content
export delimited using goodcontent.txt,replace
*调用Python分词
clear all
python
import jieba.posseg
word=[]
with open(r"goodcontent.txt",encoding="utf8") as f:
for i in f.readlines():
str=i
word.append(str)
jieba.load_userdict(r"dict.txt") #添加自定义词典
with open("好评分词.txt","w",encoding="utf8") as f2:
for unit in word:
seg_list = jieba.posseg.cut(unit)
for word in seg_list:
f2.write(word.word+" "+word.flag+"\n")
end

*分词结果导入Stata,并删除单字、缺失值、停用词
import delimited using 好评分词.txt, clear encoding("utf-8")
split v1,p(" ")
drop v1
rename (v11 v12) (keyword flag)
drop if ustrlen(keyword) == 1 // 删除单字
drop if keyword =="" //删除缺失值
preserve
import delimited using 停用词表.txt, clear ///
encoding("utf-8") varname(nonames)
outsheet using 停用词表.txt, replace nonames noquote
levelsof v1, local(keyword)
restore
foreach word in `keyword' {
drop if keyword == "`word'" //删除停用词
}

*词频统计
bysort keyword: gen frequency = _N
gsort -frequency
duplicates drop
save goodword,replace

*绘制词云图
use goodword,clear
keep if ustrregexm(flag, "^[anv]")
keep in 1/200
wordcloud keyword frequency using 好评词云.html, replace size(15 80) range(3840 2160)
shellout 好评词云.html
小编在处理过程中发现得到的好评有35万字、中评57万字、差评59万字,加起来大约150万字的有效影评足以代表影迷们整体态度。

在分析词云图时,一个有意思的地方在于同一个词在不同的评价中,所代表的用户态度应该是不同的。例如 故事 一词在三种不同的评价中所代表的含义应该不同,在好评中代表观众对故事的认可,在中评中代表观众对故事情节的褒贬不一,在差评中代表对故事的不满。同样的结果会有不同的解读,大家可以自行分析到底什么元素引起了影迷的喜欢,什么元素引起了影迷的厌恶,本文仅代表小编个人态度,具体的词云图如下所示:

好评词云图

好评词云图出现频数最高的十个词分别是好看、故事、探案、唐人街、期待、搞笑、侦探、喜欢、陈思诚、案件。这些词与《唐探1》和《唐探2》的契合度也十分的高,可以看出唐探系列深受观众喜爱的点就是其核心的唐人街、侦探和喜剧。这三者可以说是唐探系列的根,陈思诚巧妙地将三者融合在一起,通过唐探系列逐步建立了极具特色的侦探宇宙,填补了侦探世界鲜有中国人身影的空白,开辟了属于自己的电影道路,即使其中存在瑕疵,也让喜爱唐探、认可唐探、期待唐探的观众,仍然认为《唐探3》是一部好作品。

中评词云图

中评词云图出现频数最高的十个词分别是侦探、小林、喜剧、密室、探案、搞笑、期待、陈思诚、导演、案件。一般来说中评既可以意味着电影有褒有贬,也可以说是平庸。中评部分观众可能认为《唐探3》有其可取之处,但缺点也十分明显。《唐探3》选取了极具话题度的东京作为故事发生点,以案件题材中极具代表性的密室杀人案作为主线,将Q的身份揭秘穿插其中,又有大量的搞笑情节调味,本身是有一定优点的,但主体案件逻辑松散,部分情节冗余刻意,没有抓住本格推理的关键等问题也十分突出,难以达到观众心中的绝对好片标准。对比好评中新出现的小林,密室,以及虽然频数没有到达前十、但依旧很高的失望、广告、尴尬等词来看,中评里已经出现了对推理不够精彩和广告植入的不满了。

差评词云图

差评词云图出现频数最高的十个词分别是搞笑、密室、陈思诚、侦探、小林、喜剧、凶手、组织、广告、强行。差评中广告、强行、尴尬等词频数的上升,可以明显看出影迷对电影逻辑性和广告植入的不满。《唐探3》作为侦探电影的推理逻辑性不足,迷失本格灵魂和频繁的广告植入可以说是严重伤害了影迷们的期待,前两部的珠玉在前,更是将这两个缺陷暴露的更加明显。或许,差评中出现频繁的搞笑一词是影迷们对电影的一种讽刺吧。从上文中三个词云图可以看出电影中的搞笑、探案、唐人街等元素还是《唐探3》中得到了观众认可的,但是在中评和差评中出现的广告和尴尬体现了用户给出负面评价的理由,其实在观影中确实能感受到影片想展示很多东西,比如本格、黑帮等日本元素和结构性暴力的社会话题,但是效果都不太好,某某精英五大灵童的广告出场更是将观影体验降至最差。陈思诚的野心很大,但贪多嚼不烂,所谓期望越大,失望越大,在电影观众期待了一年的时间之后,看到如此的影片质量,低分也就在所难免的了。《唐探3》的票房目前已经超过40亿,希望陈导能够沉下心来,好好打磨唐探宇宙,将这个原创IP发扬光大,让唐人街的侦探故事继续走下去。

ps:本文使用的程序、数据和绘制词云图需要的配置,大家可以通过在公众号后台回复“唐探3”获取哦,喜欢的话帮忙点个在看吧~




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

爬虫俱乐部年度总结|《请回答2020》

春节假期临近,来爬爬豆瓣看看有什么好剧
putdocx生成Word文档so easy!

模糊匹配我只用这一招!

利用tushare获取财务数据

爬虫实战|Selenium爬取微信公众号标题与链接

轻轻一点,就知有没有|rqrs命令介绍

强大的正则表达式

自动群发邮件(二)——附带附件

自动群发邮件--email和smtplib基本模块的使用

批量处理变量名和标签的小方法

计算工作日的小能手——workdays

Seminar | 企业错报与银行贷款合同

Seminar | 共同基金行业的性别歧视
Seminar | 来自女儿的塑造:高管、女性社会化与企业社会责任

小贴士:Markdown的基本语法

听说相貌也能量化 | 调用百度人脸检测API实现颜值打分

列出指定属性的变量|findname命令比ds命令

新一代的标签转码小能手
【爬虫实战】亚马逊网站Top100畅销书爬取

Json文件好帮手——JsonPath

数据转置pro之sxpose2
文件"搬家"小助手:mvfiles

pyecharts绘图——河流图展示

你知道MDPI期刊的热门题目吗?

文件合并你不行,mergemany来帮宁
关于我们


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

此外,欢迎大家踊跃投稿,介绍一些关于stata和python的数据处理和分析技巧。
投稿邮箱:statatraining@163.com
投稿要求:
1)必须原创,禁止抄袭;
2)必须准确,详细,有例子,有截图;
注意事项:
1)所有投稿都会经过本公众号运营团队成员的审核,审核通过才可录用,一经录用,会在该推文里为作者署名,并有赏金分成。
2)邮件请注明投稿,邮件名称为“投稿+推文名称”。
3)应广大读者要求,现开通有偿问答服务,如果大家遇到有关数据处理、分析等问题,可以在公众号中提出,只需支付少量赏金,我们会在后期的推文里给予解答。

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

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