其他
《唐探3》做错了什么?|来自150万字影评的证据
本文作者:任 哲, 中南财经政法大学经济学院
本文编辑:王 彤
技术总编:戴 雯
爬虫俱乐部云端课程
导读
本该去年春节档上映的《唐人街探案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被封哦。爬取到的结果如下:*从影评源代码中提取评分和影评
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," |-|;","")
rename v2 content
keep title score content
save 影评.dta ,replace
这样就得到了《唐探3》最受欢迎的3000条影评的评分和内容。如下图所示,可以发现在变量score中,有的评分为“.”,这是用户只写了影评但是没有打分,由于无法直观看出该用户的倾向,故在后续的分析之中我们要把这些影评删除。影评分析
上文中得到了《唐探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))
*分词处理
**好评
*导出为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万字的有效影评足以代表影迷们整体态度。故事
一词在三种不同的评价中所代表的含义应该不同,在好评中代表观众对故事的认可,在中评中代表观众对故事情节的褒贬不一,在差评中代表对故事的不满。同样的结果会有不同的解读,大家可以自行分析到底什么元素引起了影迷的喜欢,什么元素引起了影迷的厌恶,本文仅代表小编个人态度,具体的词云图如下所示:爬虫俱乐部年度总结|《请回答2020》
模糊匹配我只用这一招!
利用tushare获取财务数据
爬虫实战|Selenium爬取微信公众号标题与链接
强大的正则表达式
自动群发邮件(二)——附带附件
自动群发邮件--email和smtplib基本模块的使用
计算工作日的小能手——workdays
Seminar | 企业错报与银行贷款合同
小贴士:Markdown的基本语法
听说相貌也能量化 | 调用百度人脸检测API实现颜值打分
列出指定属性的变量|findname命令比ds命令
Json文件好帮手——JsonPath
pyecharts绘图——河流图展示
你知道MDPI期刊的热门题目吗?
微信公众号“Stata and Python数据分析”分享实用的stata、python等软件的数据处理知识,欢迎转载、打赏。我们是由李春涛教授领导下的研究生及本科生组成的大数据处理和分析团队。
1)必须原创,禁止抄袭;
2)必须准确,详细,有例子,有截图;
注意事项:
1)所有投稿都会经过本公众号运营团队成员的审核,审核通过才可录用,一经录用,会在该推文里为作者署名,并有赏金分成。
2)邮件请注明投稿,邮件名称为“投稿+推文名称”。
3)应广大读者要求,现开通有偿问答服务,如果大家遇到有关数据处理、分析等问题,可以在公众号中提出,只需支付少量赏金,我们会在后期的推文里给予解答。