python爬虫与数据分析之《向往的生活爬取》

《向往的生活》弹幕爬取与分析

该项目参照于公众号“超哥的杂货铺”《《向往的生活3》弹幕爬取与分析》一文
链接:公众号文章链接.
本文在参考文章的基础上添加了一些自己的理解,多了不少注释,更加详细

1.1弹幕的爬取

注:本次代码主要使用requests库,抓取结果存储在CSV文件中

1.1.1 网页分析

在芒果TV网页版打开第5期节目,等待广告加载完毕,同时打开chrome开发者工具的network选项卡。由于请求很多,而且随着时间推移,会越来越多。所以我采取了先清空再等待的方式。发现前面大多加载的都是图片,自然这不是我们的目标。过了一会儿之后,发现一条可疑的请求,见下图所示,点击一看,真的出现了弹幕内容。interval是60,猜测可能是表示一个间隔,每60s会有一个新的请求。于是使用filter过滤了以“rdb”开头的请求,发现这些都是弹幕,而且next都是60000的倍数,猜测表示的是60000毫秒,也就是60秒。
找到弹幕请求链接
图1 找到弹幕请求链接

在这里插入图片描述
图2 过滤弹幕请求

接下来我们需要确认弹幕的翻页逻辑,也就是这些弹幕链接的统一规律。这里推荐一个很好用的网页请求分析工具postman。它不仅可以用来分析网页的请求参数,还能够提供不同语言的请求代码,稍加修改就可以使用。把刚刚我们找到的链接贴到postman中。如图所示,可以看到请求的参数,点击send按钮之后能看到请求的结果。由于参数很多,可以考虑去掉一些无用的参数。最终发现,只需要保留vid,cid,time三个参数即可。猜测vid表示节目id,cid表示视频id,time应该是请求时刻,是一个相对值。并且请求结果中,而每一条弹幕的时间,都要比time数值大。结合上文的分析逻辑,可以得出每一个请求结果都是请求时间60s内的弹幕。如果我们要获取所有的弹幕,就可以通过改变time的值来实现。最小的time取值应该是0,最大的应该就是和视频时长最接近的60000倍数的毫秒数。这里的节目时长为89:49。经过验证,果然如此,接下来我们就可以用代码来实现了。
在这里插入图片描述
图3 使用postman测试请求参数

在这里插入图片描述
图4 使用postman测试time请求参数

1.1.2代码实现

# 使用requests构造网络请求,并用一个循环控制翻页,爬取全部的弹幕。解析返回的json数据并使用pandas存储到Excel中。详细代码如下所示,一共45行。
import requests 
import pandas as pd   # 最终要保存为csv格式
import time     # 用于暂停
import datetime     # 用于返回当前时间
from fake_useragent import UserAgent   # 用于生成随机代理


ua = UserAgent()
url = "https://galaxy.bz.mgtv.com/rdbarrage"  # Request URL通式

# rdb_content存储所有弹幕及其相关的信息,每个弹幕有6种信息
rdb_content = {'id': [], 'type': [], 'uid': [],
               'content': [], 'add_time': [], 'ups': []}
count = 0

print("爬取开始时间:{}".format(datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')))

# 在找到弹幕的翻页逻辑之后,用循环遍历所有的弹幕
for i in range(91):

    # 请求字符串,在网页的Headers中的Query String Parameters部分
    # 除了变量部分的value为数字外其余部分都为str
    querystring = {"version": "2.0.0", "vid": "5683459",
                   "cid": "328724", "time": i*60000}

    # 此部分在网页Headers中的Request Headers部分
    # abs 随机生成一个UserAgent
    headers = {
        'User-Agent': ua.random
    }

    try:
        # 发送请求,得到json数据,response中有data,msg,seq,status(由网页可知的)
        # 请求需要的信息都在Headers里面,返回的信息在Preview里面(jsonXXXX)
        response = requests.request("GET", url, headers = headers, params=querystring).json()
        # 弹幕在'data'中的items里面
        items = response['data']['items']
        if items is None:
            print("爬取完毕!弹幕数量{}".format(count))
            break
        else:
            # 存储所有弹幕相关信息并计数
            for item in items:
                rdb_content['id'].append(item.get('id'))  # 弹幕id
                rdb_content['type'].append(item.get('type'))  # 弹幕类型
                rdb_content['uid'].append(item.get('uid'))  # 用户id
                rdb_content['content'].append(item.get('content'))  # 弹幕内容
                rdb_content['add_time'].append(item.get('time'))  # 弹幕时间
                rdb_content['ups'].append(item.get('up'))  # 弹幕点赞数
                count += 1

            print("爬取第{}分钟的弹幕...,当前弹幕数量{}".format(i+1, count))

        # 爬取完一次暂停5秒钟
        time.sleep(5)

    # 报错的话
    except:
        print("第{}分钟弹幕爬取失败!当前弹幕数量{}".format(i+1, count))
        continue   # 不会因为中间过程中弹幕爬取失败而结束

    # 存储第i+1分钟的内容到csv文件中去
    rdb_df = pd.DataFrame(rdb_content)    # 先要强行转为DataFrame类型的数据
    # 对于DataFrame类型的数据有转存为CSV类型数据的方法to_csv
    rdb_df.to_csv('rdb.csv', index=None)

运行效果截图:
在这里插入图片描述
图5 运行效果截图

可以看出,在本次爬取时,弹幕数量已经将近3w条,而此时节目更新还不到2天,在一定程度可以反映出该节目的火爆程度。接下来我们对弹幕数据做一些深入的分析,从数据的角度看这期节目。

1.2 数据的可视化

1.2.1 不同时间段弹幕数量的分布

节目时长大约90分钟,我们分别以1分钟和10分钟为单位,看一下弹幕数量。每分钟弹幕都在200以上,最小的为207,最大的为360,平均值为318。30-40分钟弹幕最多,一般此时是节目的高潮时段,80-90分钟弹幕数量最少,此时节目已经接近尾声。可以看出,虽然随着时间推移,弹幕数量有所波动,但整体来讲,在各个时间,弹幕波动不剧烈,也反映出节目能够持续保持较高的热度,可谓“分分钟都是精彩”。
在这里插入图片描述
**图6 每分钟弹幕数量柱形图 **

在这里插入图片描述
图7 每十分钟弹幕数量柱形图

1.2.2 不同长度的弹幕数量分布

在这里插入图片描述
图8 不同弹幕长度柱形图

可以看出,弹幕长度最大为64,长度越长,弹幕数量越少,长度为6的弹幕数量最多,达到2470条。大多数弹幕的长度都集中于10个字上下,趋向于口语化。这也符合我们的认知,10字左右已经足以表达用户看剧的心情和观点。当然也有不嫌麻烦的用户,弹幕数量达到了30字以上,也有极少量的弹幕长度达到了50以上。出于好奇,我们可以看一下长度超过50的弹幕都说了啥,见下图所示,多少能够感受到观众十分走心地在享受节目。

在这里插入图片描述
图9 长度超过50的弹幕

1.2.3 弹幕点赞数分布

在这里插入图片描述
图9 点赞数量区间

可以看出有接近四分之一分弹幕没有获得点赞。近6成的弹幕点赞量在20以下,点赞量20以上的弹幕不到20%。我们同样可以看一下点赞大于300的弹幕都说了啥,但从弹幕就能感受到节目整体的欢乐气氛。

在这里插入图片描述
图10 点赞超过300弹幕

1.2.4 用户发布的弹幕数量,点赞数,弹幕总字数对比

我们的数据中共有17268名用户发布了28602条弹幕,人均发布弹幕1.66条。按照点赞数降序排列取前10,观察弹幕数量,点赞数,弹幕总字数。可以看出,点赞数高的用户,发布的弹幕数量也多,字数相应也很多。下图只展示了前10的情况,也可以调整下面的区间,看更多用户的弹幕表现。需要指出的是,只能取到用户ID,无法分析用户的偏好情况。

在这里插入图片描述
图11 各用户弹幕情况对比

1.2.5 弹幕使用emoji表情情况

在这里插入图片描述
图12 弹幕emoji表情使用情况

我们的数据中,使用表情的弹幕数量为1430,共使用了166种,2439次表情,"笑哭"?这个表情使用数量最多,远远超过其他表情。一定程度上说明了这个表情受欢迎的程度,也侧面反映出节目本身的幽默效果很多,让网友们哭笑不得。

1.2.6 词云图

通过对弹幕进行分词处理,绘制出以下的词云图。
在这里插入图片描述
图13 弹幕词云图

看着这个词云图,瞬间感觉有溢出屏幕的欢乐,好像耳朵也能音乐听见断断续续的“哈哈哈哈”声,群众的眼睛是雪亮的,能让人如此开心的节目,火起来自然也就不足为奇了。

至此,我们基本完成了《向往的生活》第5期节目弹幕的抓取与简单的可视化分析工作。

发布了11 篇原创文章 · 获赞 25 · 访问量 5969

猜你喜欢

转载自blog.csdn.net/qq_41196612/article/details/101295536