整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

python爬取7w+「赘婿」弹幕,发现弹幕比剧还精彩

.前言

在上一篇文章【[以『赘婿』为实战案例,手把手教会你用python爬取『爱奇艺』视频弹幕]】,教会了大家如何爬取爱奇艺弹幕

本文将在上文的基础上继续完善,爬取更多的弹幕数据进行可视化分析!

同样还是以『赘婿』为例,下面将爬取全部弹幕数据,约7w+条数据!!!

2.采集数据

1.寻找url




上文介绍到,每一集都需要通过查看数据把获取弹幕的url

因此,我们需要去获取这些的弹幕url!!!


tv_name_list =[
'',
'/54/00/7973227714515400',
'/57/00/4779805474835700',
'/37/00/1016845483273700',
'/77/00/8679935826337700',
'/46/00/7197533339804600',
'/48/00/8042213977424800',
'/98/00/2262609044749800',
'/94/00/1699488619659400',
'/47/00/1805374511564700',
'/46/00/1933721047194600',
'/08/00/7232026471250800',
'/59/00/8982352350925900',
'/43/00/4702797553454300',
'/38/00/2151107991923800',
'/93/00/8357465155589300',
'/29/00/2071693573022900',
'/71/00/4646645944127100',
'/39/00/1182091647913900',
'/31/00/7711721648193100',
'/58/00/2099769377685800',
'/83/00/3042314248738300',
'/21/00/2889100571832100',
'/98/00/3374410909698000',
'/37/00/4335405595243700',
'/32/00/5215381530163200',
'/11/00/2379725258541100',
'/48/00/4872856713204800',
'/08/00/1488519001760800',
]

以上就是弹幕url参数!!!

2.请求数据


def get_data():
    for k in range(1,len(tv_name_list)):#29个 1-28
        url_id = tv_name_list[k]
        for x in range(1,11):
            # x是从1到11,11怎么来的,这一集总共46分钟,爱奇艺每5分钟会加载新的弹幕,46除以5向上取整
            try:
                url = 'https://cmts.iqiyi.com/bullet'+str(url_id)+'_300_' + str(x) + '.z'
                xml = download_xml(url)
                # 把编码好的文件分别写入个xml文件中(类似于txt文件),方便后边取数据
                with open('./lyc/zx'+str(k) +'-'+ str(x) + '.xml', 'a+', encoding='utf-8') as f:
                    f.write(xml)
            except:
                pass




这样就可以将含有的弹幕信息的xml文件下载到本地!

3.合并数据到excel


import openpyxl
outwb = openpyxl.Workbook()  # 打开一个将写的文件
outws = outwb.create_sheet(index=0)  # 在将写的文件创建sheet

"""
import xlwt
# # 创建一个workbook 设置编码
workbook = xlwt.Workbook(encoding = 'utf-8')
# # 创建一个worksheet
worksheet = workbook.add_sheet('sheet1')
#
# # 写入excel
# # 参数对应 行, 列, 值
# worksheet.write(0,0, label='index')
# worksheet.write(0,1, label='tvname')
# worksheet.write(0,2, label='uid')
# worksheet.write(0,3, label='content')
# worksheet.write(0,4, label='likeCount')
"""
outws.cell(row = 1 , column = 1 , value = "index")
outws.cell(row = 1 , column = 2 , value = "tvname")
outws.cell(row = 1 , column = 3 , value = "uid")
outws.cell(row = 1 , column = 4 ,  value = "content")
outws.cell(row = 1 , column = 5 , value = "likeCount")

避坑:
之前我们使用xlwt来保存数据到excel,但是最多写到65535行,这次我们采用openpyxl来写入到excel!!!


def xml_parse(file_name,tv__name):
    global  count
    DOMTree = xml.dom.minidom.parse(file_name)
    collection = DOMTree.documentElement
    # 在集合中获取所有entry数据
    entrys = collection.getElementsByTagName("entry")

    for entry in entrys:
        uid = entry.getElementsByTagName('uid')[0]
        content = entry.getElementsByTagName('content')[0]
        likeCount = entry.getElementsByTagName('likeCount')[0]
        #print(uid.childNodes[0].data)
        #print(content.childNodes[0].data)
        #print(likeCount.childNodes[0].data)
        # 写入excel
        # 参数对应 行, 列, 值
        outws.cell(row=count, column=1, value=str(count))
        outws.cell(row=count, column=2, value=str("第"+str(tv__name)+"集"))
        outws.cell(row=count, column=3, value=str(uid.childNodes[0].data))
        outws.cell(row=count, column=4, value=str(content.childNodes[0].data))
        outws.cell(row=count, column=5, value=str(likeCount.childNodes[0].data))
        count=count+1

这样就可以将xml里的数据保存到excel


def combine_data():
    for k in range(1,29):
        for x in range(1,11):
            try:
                xml_parse("./lyc/zx"+str(k) +"-"+ str(x) + ".xml",k)
                print(str(k) + "-" + str(x))
            except:
                pass
    # 保存
    #workbook.save('弹幕数据集-李运辰.xls')
    outwb.save("弹幕数据集.xls")  # 保存结果


这样7w+条弹幕数据可以完全写入到excel中,命名为 弹幕数据集.xls

3.数据可视化

1.浏览数据


# 导包
import pandas as pd

#读入数据
df_all = pd.read_csv("弹幕数据集.csv",encoding="gbk")
df = df_all.copy()

# 重置索引
df = df.reset_index(drop=True)
print(df.head())




说明:1.index序号、2.tvname集数、3.uid用户id、4.content评论、5.likeCount评论点赞数

2.累计发送弹幕数的用户


#累计发送弹幕数的用户
def an1():
    danmu_counts = df.groupby('uid')['content'].count().sort_values(ascending=False).reset_index()
    danmu_counts.columns = ['用户id', '累计发送弹幕数']
    name = danmu_counts['用户id']
    name = (name[0:10]).tolist()
    dict_values = danmu_counts['累计发送弹幕数']
    dict_values = (dict_values[0:10]).tolist()

    # 链式调用
    c = (
        Bar(
            init_opts=opts.InitOpts(  # 初始配置项
                theme=ThemeType.MACARONS,
                animation_opts=opts.AnimationOpts(
                    animation_delay=1000, animation_easing="cubicOut"  # 初始动画延迟和缓动效果
                ))
        )
            .add_xaxis(xaxis_data=name)  # x轴
            .add_yaxis(series_name="累计发送弹幕数的用户", yaxis_data=dict_values)  # y轴
            .set_global_opts(
            title_opts=opts.TitleOpts(title='', subtitle='',  # 标题配置和调整位置
                                      title_textstyle_opts=opts.TextStyleOpts(
                                          font_family='SimHei', font_size=25, font_weight='bold', color='red',
                                      ), pos_left="90%", pos_top="10",
                                      ),
            xaxis_opts=opts.AxisOpts(name='用户id', axislabel_opts=opts.LabelOpts(rotate=45)),
            # 设置x名称和Label rotate解决标签名字过长使用
            yaxis_opts=opts.AxisOpts(name='累计发送弹幕数'),

        )
            .render("累计发送弹幕数的用户.html")
    )


3.查看某个用户评论情况


#查看某个用户评论情况
def an2():
    df_top1 = df[df['uid'] == 2127950839].sort_values(by="likeCount", ascending=False).reset_index()
    print(df_top1.head(20))


4.用户(2127950839)每一集的评论数


#查看用户(2127950839)每一集的评论数
def an3():
    df_top1 = df[df['uid'] == 2127950839].sort_values(by="likeCount", ascending=False).reset_index()
    data_top1 = df_top1.groupby('tvname')['content'].count()
    print(data_top1)
    name = data_top1.index.tolist()
    dict_values = data_top1.values.tolist()
    # 链式调用
    c = (
        Bar(
            init_opts=opts.InitOpts(  # 初始配置项
                theme=ThemeType.MACARONS,
                animation_opts=opts.AnimationOpts(
                    animation_delay=1000, animation_easing="cubicOut"  # 初始动画延迟和缓动效果
                ))
        )
            .add_xaxis(xaxis_data=name)  # x轴
            .add_yaxis(series_name="查看用户(2127950839)每一集的评论数", yaxis_data=dict_values)  # y轴
            .set_global_opts(
            title_opts=opts.TitleOpts(title='', subtitle='',  # 标题配置和调整位置
                                      title_textstyle_opts=opts.TextStyleOpts(
                                          font_family='SimHei', font_size=25, font_weight='bold', color='red',
                                      ), pos_left="90%", pos_top="10",
                                      ),
            xaxis_opts=opts.AxisOpts(name='集数', axislabel_opts=opts.LabelOpts(rotate=45)),
            # 设置x名称和Label rotate解决标签名字过长使用
            yaxis_opts=opts.AxisOpts(name='评论数'),

        )
            .render("查看用户(2127950839)每一集的评论数.html")
    )


5.剧集评论点赞数最多的评论内容


#剧集评论点赞数最多的评论内容
def an4():
    df_like = df[df.groupby(['tvname'])['likeCount'].rank(method="first", ascending=False) == 1].reset_index()[['tvname', 'content', 'likeCount']]
    df_like.columns = ['集', '弹幕内容', '点赞数']
    print(df_like)


6.评论内容词云


#评论内容词云
def an5():
    contents = (df_all['content']).tolist()

    text = "".join(contents)
    with open("stopword.txt", "r", encoding='UTF-8') as f:
        stopword = f.readlines()
    for i in stopword:
        print(i)
        i = str(i).replace("\r\n", "").replace("\r", "").replace("\n", "")
        text = text.replace(i, "")
    word_list = jieba.cut(text)
    result = " ".join(word_list)  # 分词用 隔开
    # 制作中文云词
    icon_name = 'fas fa-play'
    gen_stylecloud(text=result, icon_name=icon_name, font_path='simsun.ttc',
                   output_name="评论内容词云.png")  # 必须加中文字体,否则格式错误


4.总结

1.爬取了7w+『赘婿』弹幕,保存到excel(数据分享给大家)!
2.通过pandas读取excel并进行相关统计计算!
3.以可视化方式
分析好的数据进行可视化展示!

信小伙伴们逛B站的时候都见到过B站的字幕可以不遮挡人物的效果。

那么B站到底是如何实现这么神奇的效果的呢?经过一番摸索最终发现了其中的奥秘

主要是通过一行CSS属性mask-image:设置了一张图片为做元素的蒙版,使用人形图片遮挡住了弹幕

实践出真知:上demo

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
  <style>
    .video {
      width: 668px;
      height: 376px;
      position: relative;
      -webkit-mask-image: url("mask.svg");
      -webkit-mask-size: 668px 376px;
    }
    .bullet {
      position: absolute;
      font-size: 20px;
    }
  </style>
</head>
<body>
<div class="video">
  <div class="bullet" style="left: 100px; top: 0;">元芳,你怎么看</div>
  <div class="bullet" style="left: 200px; top: 20px;">你难道就是传说中的奶灵</div>
  <div class="bullet" style="left: 300px; top: 40px;">你好,我是胖灵</div>
  <div class="bullet" style="left: 400px; top: 60px;">这是第一集,还没有舔灵</div>
</div>
</body>
</html>

效果图:

加个红色背景效果更明显一些:

那么这种图片是怎么来的呢?

这应该用到了AI识别视频人物的算法,可以自动检测视频中的人物、物体和其他重要区域,然后根据它们的运动轨迹进行弹幕屏蔽。

具体来说,B站的弹募播放器使用计算机视觉算法对视频中的每一帧进行分析,提取人物、物体等的边缘特征和运动信息,然后根据这些信息计算出它们的运动轨迹。当弹幕出现在视频的特定区域时,播放器会根据这些运动轨迹动态地调整弹幕的显示位置,以避免弹幕挡住视频中的人物、物体等重要信息。

当然mask不止有image这一个属性,还有如border、clip等等,感兴趣的话可以都了解一下

mask - CSS锛氬眰鍙犳牱寮忚〃 | MDNMDN Web DocsMDN logoMozilla logo

开源精选》是我们分享Github、Gitee等开源社区中优质项目的栏目,包括技术、学习、实用与各种有趣的内容。本期推荐的是一个开源的 HTML5 视频播放器插件——MuiPlayer。


MuiPlayer 是一个开源的HTML5视频播放插件,其默认配置了精美可操作的的播放控件,涉及了常用的播放场景,例如全屏播放、播放快进、循环播放、音量调节等功能。支持 mp4、m3u8、flv 等多种媒体格式播放,解决大部分兼容问题,同时适应在PC、手机端播放。


特点

  • 各浏览器平台播放 ui 不能统一
  • ui 扩展之间以及状态处理容易产生冲突
  • 在不同环境下(android、ios、pc)针对 h5 video api 可能触发事件的时机尽不相同
  • 媒体格式存在各种兼容问题,muiplayer 处理了大多数在不同环境下播放的兼容问题
  • 具有丰富的参数可以自定义播放器实例,通过轻松的配置即可完成自定义场景的视频播放

快速开始

  • 安装

使用 npm 安装:

npm i mui-player --save

使用 yarn 安装:

yarn add mui-player
  • 使用

1 使用 script 标签引入:

<!-- 引入基础样式文件 mui-player.min.css -->
<link rel="stylesheet" type="text/css" href="css/mui-player.min.css"/>

<!-- 引入基础脚本 mui-player.min.js -->
<script type="text/javascript" src="js/mui-player.min.js"></script>

<!-- 指定播放器容器 -->
<div id="mui-player"></div>

或者使用模块管理器引入:

import 'mui-player/dist/mui-player.min.css'
import MuiPlayer from 'mui-player'

2 定义播放器容器

<div id="mui-player"></div>

3 初始化构建播放器

// 初始化 MuiPlayer 插件,MuiPlayer 方法传递一个对象,该对象包括所有插件的配置
var mp = new MuiPlayer({
    container:'#mui-player',
    title:'标题',
    src:'./static/media/media.mp4',
})

以上就能为初始化构建一个具有默认配置控件的视频播放器。

更多API基础配置: https://muiplayer.js.org/zh/guide/api.html#%E4%B8%BB%E8%A6%81%E9%85%8D%E7%BD%AE


效果演示

  • 基础效果

  • 直播模式

  • 播放字幕

  • 播放弹幕

  • 多窗口播放


更多内容大家可自行前往阅读。

开源地址:https://gitee.com/muiplayer/hello-muiplayer