查看原文
其他

疫情下的家庭关系|《请回答1988》影评爬取

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

本文作者:张馨月

文字编辑:朱巧利

技术总编:张计宝

导读

一场疫情将我们困在了家中,对很多人来说,这都是在外求学工作多年后与家人相处最久的时间,四个多月过去,我们与家人的相处从疫情初期的彼此相守转变成现在“靠洗碗维持的亲情”,这段意外获得的与家人24h相处的时光,也让我们对自己与亲情有了新的理解。虽然家中有父母的嫌弃唠叨和亲戚突然的关心,但这里依然是我们最为依赖、最不可割舍的地方。在与家庭相关的众多影视作品中,最深受大家喜爱的作品之一便是《请回答1988》,双门洞的故事倒映着我们的生活,也让当下平常的日子显得更为珍贵。今天我们就用Stata来分析一下关于这部剧,豆瓣网友都留下了哪些内容~


本文主要介绍的内容如下:

1.豆瓣影评内容爬取

2.影评内容分析(数据统计与文本分析)


1.影评内容爬取


豆瓣影评的获取需要进行两层爬虫,第一层对所有页面遍历,获取每位用户影评的标题与链接,第二层对链接进行抓取,并提取出需要的内容。在之前的推文《少年的你影评》当中,我们介绍了爬取的详细过程并主要使用了命令split进行提取,今天的介绍将采取类似的思路,并使用正则表达式来提取关键内容。

以第一页为例,我们首先使用copy命令获取源代码并导入到Stata当中:
copy "https://movie.douban.com/subject/26302614/reviews?start=10" temp.txt,replaceinfix strL v 1-100000 using temp.txt, clear

观察源代码,可以发现影评的标题与链接都在标签</a></h2>所在行中:

因此,我们先使用ustrregexm()匹配</a></h2>所在的行,再用ustrregexs() 提取href=””中的链接,最后使用ustrregexra()将<>中的内容替换为空,便可得到标题。过程如下:

keep if ustrregexm(v,`"</a></h2>"')gen url=ustrregexs(1) if ustrregexm(v,`"<a href="(.*)">"')replace v=ustrregexra(v,"<.*?>","")rename v title

对于所有页面的抓取,需要先从第一页的源代码中提取总页数,再遍历所有页面进行提取,并将每一页的内容进行合并。代码如下:

copy "https://movie.douban.com/subject/26302614/reviews?start=10" temp.txt,replaceinfix strL v 1-100000 using temp.txt, clear
*提取页码keep if index(v,`"<span class="thispage" data-total-page="') replace v=ustrregexs(0) if ustrregexm(v,"(\d+)") //共有多少页评论local p=v[1]
*第一层爬取:对页码循环forvalues i=1/`p'{ local j=(`i'-1)*20 //定义评论对应的数字编码 cap copy "https://movie.douban.com/subject/26302614/reviews?start=`j'" temp.txt,replace while _rc!=0{ cap copy "https://movie.douban.com/subject/26302614/reviews?start=`j'" temp.txt,replace } infix strL v 1-10000 using temp.txt,clear keep if ustrregexm(v,`"</a></h2>"') gen url=ustrregexs(1) if ustrregexm(v,`"<a href="(.*)">"') replace v=ustrregexra(v,"<.*?>","") rename v title save "影评_`i'",replace }*合并文件 clearlocal files:dir "." file "影评*.dta"foreach file in `files'{ append using "`file'" //把上面生成的影评i.dta合并起来 }drop if url==""save "影评.dta",replace

接下来,我们使用fileread()对每一个url进行抓取,按照与上述类似的思路,从中提取出影评的内容、评分和点赞数:

*第二层爬取:抓取影评所在网页gen v=""forvalues i=1/`=_N'{ sleep 100 replace v=fileread(url) in `i' while filereaderror(v[`i'])!=0 { sleep 5000 //休息5000毫秒 replace v=fileread(url) in `i' } dis `i' }gen score=ustrregexs(1) if ustrregexm(v,"allstar([0-9]{2})") //提取评分destring score,replace replace score=score/10gen like=ustrregexs(1) if ustrregexm(v,`" data-ad-ext="有用(\d+)"') //提取点赞数destring like,replacegsort -likesplit 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 contentkeep title score like content save "影评.dta",replace


2.内容分析


《请回答1988》在豆瓣的评分高达9.7,小编也对撰写影评的用户评分进行了统计,结果显示给这部剧打出5星好评的用户占比高达87.86%,而1分评级的占比仅为0.6%:


对于饼状图的绘制,我们先用collapse命令分组统计并对数据进行处理,再用graph pie输出图像,相关命令的介绍可以参考推文《利用collapse命令转化原始数据》《客官,来个饼图!》。

use 影评.dta,clearcollapse (count) like,by(score) //分组统计评分数量drop if score==.egen total=sum(like) //计算评分的总数gen fre=like/totalgrstyle init //初始化图形设置grstyle set plain //去掉图形背景色graph pie fre ,over(score) pie(5,explode color(navy *0.8)) plabel(5  percent ,size(*2) color(white))

接下来,通过Stata与Python的交互实现对影评的分词处理,由于影评的内容通常较长,包括形容词、名词等多种词性,因此我们使用jieba.posseg来分词以获取每个词语的词性。(关于词频统计代码的详细介绍,可以参考推文《高亮输出之唐诗作者》):

*分词处理*导出为txt文档use 影评.dta,clearkeep contentexport delimited using content.txt,replace*调用Python分词clear allpythonimport jieba.possegword=[]with open(r"content.txt",encoding="utf8") as f: for i in f.readlines(): str=i word.append(str) jieba.load_userdict(r"tsdict.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 v1rename (v11 v12) (keyword flag)drop if ustrlen(keyword) == 1 // 删除单字drop if keyword =="" //删除缺失值preserveimport delimited using 停用词表.txt, clear /// encoding("utf-8") varname(nonames)outsheet using 停用词表.txt, replace nonames noquotelevelsof v1, local(keyword)restoreforeach word in `keyword' { drop if keyword == "`word'" //删除停用词}*词频统计bysort keyword: gen frequency = _Ngsort -frequencyduplicates dropsave word,replace

在《请回答1988》中有许多深入人心的角色,比如善良又美丽的德善、天才围棋少年阿泽、沉默的正焕、人生导师娃娃鱼等等,小编从分词结果中保留了几位主人公的名字,可以看到这些角色都被提及了非常多次:

上图绘制的代码如下:

keep if ustrregexm(keyword, "宝拉|德善|正焕|善宇|阿泽|正峰|娃娃鱼|珍珠")save name,replacekeep in 1/8sencode keyword,gen(name) gsort(-frequency)twoway bar frequency name , barwidth(0.5) xlab(1(1)8,valuelabel angle(0) labsize(*0.7))  ylabel(1000(5000)35000,angle(0) labsize(*0.5)) ytitle("") xtitle("")
最后,在分词结果中只保留动词、名词和形容词进行词云图的绘制:
use word,clearkeep if ustrregexm(flag, "^[anv]") keep in 1/100wordcloud keyword frequency using 词云.html, replace size(15 80) range(3840 2160)shellout 词云.html
结果如下图所示:

从中可以看到,“妈妈”爸爸“父母”“家庭”“美好”这些词语出现的频率都很高,而家庭与邻里之间的温情一直是这部剧的主旋律,豹子女士感觉不被需要的失落、超人爸爸担心阿泽时的情绪失控等等细节,都在提醒我们在习以为常的生活当中,是否常常忽略了父母的付出与他们的感受?无论是剧中1988年的双门洞还是当下2020年的疫情,都让每个人对亲情、友情和爱情有了更多的思考,对自我、时间与人生有了全新的感知。疫情给生活留下了不可磨灭的印记,也让我们与亲人之间的联结更为紧密,它交会我们的重要一课,便是要好好爱自己,好好珍惜身边的人。


疫情结束之后,也要记得常常联系家人~






对我们的推文累计打赏超过1000元,我们即可给您开具发票,发票类别为“咨询费”。用心做事,不负您的支持!
往期推文推荐
教你把Python当美图秀秀用(二)
自己动手进行线性回归计算
personage与年龄
原来这才是查看盲评结果的正确方式
教你把Python当美图秀秀用(一)
用数据透视表剖析泰坦尼克号乘客数据
读入文本文档,intext来帮忙
matchit——解锁文本相似度的钥匙
基于广义线性模型的机器学习算法——线性回归
听说你会魔法?
dummieslab——从分类变量到虚拟变量的“一步之遥”
线上Python课程都面向哪些方向?
子类与父类
用requests库爬取淘宝数据
WordStat—Stata的文本分析小助手
数据筛选理还乱,datacheck能诊断

如何用简单的手法绘制出不一样的海外疫情趋势图

关于我们


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

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

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

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