python scrapy框架爬取优酷世界杯评论并使用snownlp做情感分析

简介

世界杯已经结束,在优酷上有许多网友留下了对世界杯的评论,这些评论或喜悦或失望。这里我使用python的scrapy框架配合splash爬取优酷世界杯相关视屏的评论,之后使用已有的库对这些评论做相应的情感分析。

实现思路及一些问题

爬取优酷世界杯相关视屏下方的评论,在item类中添加封装类,这次爬取使用数据库存储,在settings文件中添加相关数据库配置。观察优酷视屏搜索列表代码发现,每一个视屏的内容都在class为sk-mode的div中,这样我们就可以很轻易的从splashrequest的response中提取出每个视屏的链接。

python scrapy框架爬取优酷世界杯评论并使用snownlp做情感分析

翻页按钮不是指向一个url的片段,使用http://so.youku.com/与href中的字段评接即可得到下一页的url。这里在实际操作中遇到了一个坑,由于爬取内容字符编码与python的编码不一致,会导致字符串凭借失败。报错淹没在scrapy大量的状态报告中找出这个问题着实花了不少时间。

 

在进入视屏界面后我们可以看到评论是在class为comment-item这些div中的。

python scrapy框架爬取优酷世界杯评论并使用snownlp做情感分析

按照之前爬取动态网页的方法试图从这些div中获得评论内容,却发现为空,复制response中的html代码后发现整个comment部分都是空的。这个问题困扰了我很长时间。明明都是动态生成的页面为什么单单评论这部分不出来。我又翻阅了许多爬虫教学的书籍。其中有一本书讲到了页面滑动到某一部分某些内容才加载的问题。我又在浏览器中多次尝试打开优酷的视屏页面。果然,在刚刚滑动到这个部分时评论区有一个很快速的加载过程。

 

在找出问题的原因后,按照书上的示例代码,在lua脚本中添加模拟滚动到这个位置的代码后,页面html源码里有了这些评论内容。接下来是评论页面的翻页问题,评论页面的翻页问题不同于之间接触到的网站的翻页,它在点击下一页后页面的url是不会变化的,所以需要改变传入splashrequest的lua脚本来实现翻页,我一开始的想法是到第几页就模拟点击几次下一页按钮,但是这样的话每个页面需要几秒钟时间加载,想要爬取到页码靠后的评论时间太长。所以我决定采用模拟点击页码的方式翻页,一开始我查看的页面评论页数不多,但是在运行时出现了问题,在仔细查看页面后发现,评论的页码是有一些压缩的,如下图。

python scrapy框架爬取优酷世界杯评论并使用snownlp做情感分析

所以需要写一个根据页码判断需要点击的是第几页页码按钮的方法,同时还需要根据页码生成lua语句的方法。这里需要注意的是要点击后面的页码必须先点击之前的页码。我选择的跨度是5,也就是说要想点击20这个页码,必须首先点击5,然后点击10,之后再点击15,页面才能变成上图所示的状态,根据页码判断点击位置的方法才能计算出正确的页码点击位置。

目前看来优酷评论爬虫的所有障碍都解决了,但是在实际爬取时经常会出现爬到的内容为空的情况。我在仔细思考后终于明白了这个问题的来源。因为我使用在测试lua脚本的正确性时使用的是浏览器中访问splash并在其中解析目标页面,但凡涉及到wait()函数时,我的想法是越短越好,以节省时间。但是在爬虫开启后,网络占用高再加长网络不稳定,单例测试时的时间往往不能满足大量爬取时渲染的需要,所以需要适当延长lua脚本中的wait时间以及setting中DOWNLOAD_DELAY使得所有页面完全渲染完成。

获取到数据之后,我使用python的自然语言处理库SnowNLP对爬取到的相关数据进行处理。这个库可以对一段中文进行情感判断,给出这段文字情感倾向为正向的概率值。我对评论的处理方式是:首先判断评论中是否包含球队名称,如果包含则对其进行情感倾向的判断,将其得分*(点赞数目+踩数目+1)加到这个球队的总分上面。最后算出每个球队得分的平均分。得到数据之后还是可以看出视屏观众的一些感情倾向的。比如数据显示:同为亚洲球队,我国观众对日本队和韩国队的表现的满意度差别十分明显。日本队的舆情得分明显高于韩国队。起初我还以为是出现了什么错误。但在人工浏览了评论后发现,观众普遍认为韩国队防守动作不太“干净”而认为日本队在本届世界杯中背水一战的勇气值得鼓励。由此可见这种舆情分析方式还是能说明一些问题的。