python哔哩哔哩弹幕数据分析可视化系统 B站 bilibili 弹幕 Django框架

1、项目介绍

技术栈:
Python语言、Django框架、Echarts可视化、requests爬虫、HTML
(1)B站弹幕词云图分析
(2)B站弹幕情感占比分析
(3)用户弹幕数量分布
(4)弹幕不同时间发送量分析
(5)B站弹幕列表
(6)输入需要分析弹幕的B站视频链接
(7)后台管理

随着互联网技术的快速发展,弹幕文化在视频分享平台如Bilibili(简称B站)上得到了广泛的应用。为了深入了解B站用户的弹幕行为,我们设计并开发了一款基于Python的B站弹幕分析可视化系统。该系统利用Django框架作为后端基础,结合requests爬虫获取B站弹幕数据,并使用Echarts进行数据可视化。同时,系统提供了HTML前端界面,让用户能够直观地查看和分析弹幕数据。

2、项目界面

(1)B站弹幕词云图分析

在这里插入图片描述

(2)B站弹幕情感占比分析

在这里插入图片描述

(3)用户弹幕数量分布

在这里插入图片描述

(4)弹幕不同时间发送量分析

在这里插入图片描述

(5)B站弹幕列表

在这里插入图片描述

(6)输入需要分析弹幕的B站视频链接

在这里插入图片描述

(7)后台管理

在这里插入图片描述

3、项目说明

随着互联网技术的快速发展,弹幕文化在视频分享平台如Bilibili(简称B站)上得到了广泛的应用。为了深入了解B站用户的弹幕行为,我们设计并开发了一款基于Python的B站弹幕分析可视化系统。该系统利用Django框架作为后端基础,结合requests爬虫获取B站弹幕数据,并使用Echarts进行数据可视化。同时,系统提供了HTML前端界面,让用户能够直观地查看和分析弹幕数据。

一、系统主要功能

B站弹幕词云图分析:系统通过爬虫从B站获取弹幕数据后,对弹幕文本进行分词和关键词提取,然后利用Echarts生成词云图。词云图以关键词出现频率为权重,直观地展示了弹幕中的热门话题和关注点。
B站弹幕情感占比分析:系统利用自然语言处理技术对弹幕进行情感分析,将弹幕分为积极、消极和中性三类。通过统计各类情感弹幕的数量,系统生成情感占比图,帮助用户了解用户对视频内容的情感态度。
用户弹幕数量分布:系统根据用户的弹幕发送量进行统计,生成用户弹幕数量分布图。这有助于了解不同用户在弹幕互动中的活跃度和参与度。
弹幕不同时间发送量分析:系统对弹幕的发送时间进行统计,生成弹幕发送量随时间变化的折线图。这有助于分析弹幕发送的高峰期和低谷期,以及用户在不同时间段的活跃度。
B站弹幕列表:系统提供弹幕列表功能,用户可以查看视频的弹幕内容、发送时间和发送者等信息。这有助于用户深入了解弹幕的具体内容和互动情况。
输入需要分析弹幕的B站视频链接:用户可以通过系统界面输入B站视频链接,系统将根据链接自动爬取该视频的弹幕数据并进行分析和可视化展示。
后台管理:系统提供后台管理功能,管理员可以对弹幕数据进行增删改查等操作,确保数据的准确性和安全性。
二、技术实现

本系统采用Python语言进行开发,利用Django框架构建后端系统。requests库用于实现B站弹幕数据的爬取,Echarts库则负责数据可视化。前端采用HTML进行界面展示,用户可以通过浏览器访问系统并查看分析结果。在数据处理方面,系统使用自然语言处理技术对弹幕进行分词、关键词提取和情感分析等操作,确保分析结果的准确性和可靠性。

总的来说,B站弹幕分析可视化系统通过结合Python语言、Django框架、requests爬虫、Echarts可视化和HTML等技术手段,实现了对B站弹幕数据的全面分析和可视化展示。该系统不仅有助于用户深入了解B站用户的弹幕行为和情感态度,也为B站运营和管理提供了有力的数据支持。

4、核心代码


from django.shortcuts import render
from biliapi import get_danmaku
from .models import Danmaku
import json
from django.http.response import JsonResponse, HttpResponse
from pyecharts import options as opts
from pyecharts.charts import Pie, Funnel, Bar, Scatter, Line, WordCloud, Map
from jieba.analyse import extract_tags
from bilibili import bd_sentiment, sentiment
from collections import Counter
from itertools import groupby


def get_video_danmaku(request):
    data = request.json
    bvid = data.get("bvid")
    danmaku = Danmaku.objects.filter(bvid=bvid).first()
    if not danmaku:
        result = get_danmaku(bvid)
        danmaku, created = Danmaku.objects.get_or_create(
            bvid=bvid,
            defaults=dict(bvid=bvid, result=json.dumps(result, ensure_ascii=False)),
        )
    result = json.loads(danmaku.result)
    result["bvid"] = danmaku.bvid
    return JsonResponse(result)


def duration_format(d, fullduration=None):
    """
    视频时长格式化
    :param d: 时长(秒数)
    :return:
    """
    d = int(float(d))
    result = []
    hour = int(d / (60 * 60))
    result.append("{:0>2}".format(hour))
    dd = int(d % (60 * 60))
    min = int(dd / 60)
    result.append("{:0>2}".format(min))
    sec = int(dd % 60)
    result.append("{:0>2}".format(sec))
    if fullduration and fullduration < 3600:
        return ":".join(result[1:])
    elif d < 3600:
        return ":".join(result[1:])
    return ":".join(result)


def get_danmaku_line(request):
    bvid = request.json.get("bvid")
    danmaku = Danmaku.objects.filter(bvid=bvid).first()
    result = json.loads(danmaku.result)
    durations = dict([[duration_format(i), 0] for i in range(result["duration"] + 1)])
    for i in result["danmaku"]:
        if "progress" in i:
            durations[duration_format(i["progress"] / 1000, result["duration"])] += 1
    durations = list(durations.items())
    durations.sort(key=lambda x: x[0])
    max_ = max(durations, key=lambda x: x[1])[1]
    c = (
        Line()
        .add_xaxis([i[0] for i in durations])
        .add_yaxis(
            "每秒视频弹幕量",
            [i[1] for i in durations],
            is_smooth=True,
            label_opts=opts.LabelOpts(is_show=False),
            color="rgb(56, 189, 248)",
            linestyle_opts=opts.LineStyleOpts(width=2),
        )
        .set_global_opts(
            title_opts=opts.TitleOpts(title="弹幕发送量分析", pos_left="center"),
            legend_opts=opts.LegendOpts(is_show=False),
            xaxis_opts=opts.AxisOpts(
                name="视频进度",
                name_location="center",
                name_gap=40,
                axispointer_opts=opts.AxisPointerOpts(is_show=True, type_="line"),
            ),
            yaxis_opts=opts.AxisOpts(
                name="弹幕量",
                name_location="center",
                name_gap=40,
                splitline_opts=opts.SplitLineOpts(is_show=True),
            ),
            visualmap_opts=opts.VisualMapOpts(
                range_color=["rgb(56, 189, 248)", "red"], max_=max_
            ),
        )
    )
    return HttpResponse(c.dump_options(), content_type="application/json")


def get_danmaku_wordcloud(request):
    bvid = request.json.get("bvid")
    danmaku = Danmaku.objects.filter(bvid=bvid).first()
    result = json.loads(danmaku.result)
    contentset = list(set([i["content"] for i in result["danmaku"]]))
    counter = extract_tags(" ".join(contentset), topK=200, withWeight=True)
    c = (
        WordCloud()
        .add("", counter, word_size_range=[30, 160])
        .set_global_opts(
            title_opts=opts.TitleOpts(title="弹幕词云图分析", pos_left="center"),
            legend_opts=opts.LegendOpts(is_show=False),
        )
    )
    return HttpResponse(c.dump_options(), content_type="aplication/json")


def get_danmaku_pie(request):
    bvid = request.json.get("bvid")
    danmaku = Danmaku.objects.filter(bvid=bvid).first()
    result = json.loads(danmaku.result)
    contentset = list(set([i["content"] for i in result["danmaku"]]))
    content = " ".join(contentset)
    pos, neg = bd_sentiment(content[:2000])
    # pos, neg = sentiment(content)
    result = [
        ["负向占比", neg],
        ["正向占比", pos],
    ]
    c = (
        Pie()
        .add(
            "",
            result,
            radius=["50%", "70%"],
            label_opts=opts.LabelOpts(formatter="{b}: {d}%"),
        )
        .set_colors(
            [
                "rgb(252, 165, 165)",
                "rgb(110, 231, 183)",
            ]
        )
        .set_global_opts(
            title_opts=opts.TitleOpts("弹幕情感占比分析", pos_left="center"),
            legend_opts=opts.LegendOpts(
                is_show=True, pos_left="left", pos_top="center", orient="vertical"
            ),
        )
    )
    return HttpResponse(c.dump_options(), content_type="aplication/json")


def get_danmaku_user_bar(request):
    bvid = request.json.get("bvid")
    danmaku = Danmaku.objects.filter(bvid=bvid).first()
    result = json.loads(danmaku.result)
    data = [
        [num, len(list(arr))]
        for num, arr in groupby(
            sorted(list(Counter([i["midHash"] for i in result["danmaku"]]).values()))
        )
    ]
    c = (
        Bar()
        .add_xaxis([i[0] for i in data])
        .add_yaxis(
            "",
            [i[1] for i in data],
            # bar_max_width=40,
            label_opts=opts.LabelOpts(position="top"),
            color="rgb(56, 189, 248)",
        )
        .set_global_opts(
            title_opts=opts.TitleOpts(title="用户弹幕量分布", pos_left="center"),
            legend_opts=opts.LegendOpts(is_show=False),
            xaxis_opts=opts.AxisOpts(
                name="用户发送弹幕量",
                name_location="center",
                name_gap=40,
                axislabel_opts=opts.LabelOpts(),
                axispointer_opts=opts.AxisPointerOpts(is_show=True, type_="shadow"),
            ),
            yaxis_opts=opts.AxisOpts(
                name="弹幕条数",
                name_location="center",
                name_gap=40,
            ),
        )
    )
    return HttpResponse(c.dump_options(), content_type="aplication/json")

5、源码获取方式

🍅由于篇幅限制,获取完整文章或源码、代做项目的,查看我的【用户名】、【专栏名称】、【顶部选题链接】就可以找到我啦🍅

感兴趣的可以先收藏起来,点赞、关注不迷路,下方查看👇🏻获取联系方式👇🏻

<think>好的,用户想构建一个基于Spark的哩数据情感分析系统,需要教程和示例代码。首先,我得理清整个流程。根据用户提供的引用内容,他们提到了情感趋势分析、PySpark、实时计算,还有图计算相关的内容。可能用户需要的是从数据采集到处理,再到分析可视化的完整流程。 首先,系统架构方面,可能需要分为数据采集、预处理、情感分析、趋势分析可视化这几个模块。Spark在这里主要用于处理大规模数据,特别是实时或批处理的情感分析。需要确认用户是否需要实时分析,因为引用3提到了实时计算,所以可能需要用到Spark Streaming或者Structured Streaming。 然后,数据采集部分,引用2提到Python数据分析,可能用户已经有Python的基础,所以数据采集可以用Python的爬虫框架,比如Scrapy或requests。不过B可能有反爬措施,需要注意合规性,或者使用官方API。这部分可能需要提醒用户注意遵守网规则。 接下来是预处理,Spark的DataFrame API很适合做数据清洗,比如去重、过滤无效数据、分词等。中文分词可能需要用到jieba库,但Spark本身处理分词可能需要借助UDF,或者使用现有的库。这里可能需要示例代码,比如如何用PySpark进行分词。 情感分析模型部分,用户可能不知道选择哪种模型。引用1提到了使用PySpark的分布式计算,所以最好是训练一个可以在Spark上部署的模型。可以用MLlib的机器学习管道,比如逻辑回归或者随机森林。另外,也可以考虑使用预训练的中文情感分析模型,比如SnowNLP或者THUCNews的模型,但如何在Spark中调用这些模型可能需要一些技巧,比如使用pandas UDF或者将模型序列化分发到各个节点。 实时情感趋势分析部分,引用3提到实时计算,可能需要用到Spark Streaming。这里需要示例代码展示如何对接Kafka等消息队列,处理实时数据流,并生成趋势图。同时,引用1提到生成情感趋势图,可能需要将结果存储到数据库,比如Redis或MySQL,然后通过Web应用展示。 可视化方面,引用1和2都提到了Web应用开发,可能需要用Flask或Django搭建一个简单的Dashboard,展示情感分布和趋势。Spark处理后的结果可以输出到数据库,Web应用再从数据库读取数据,用Matplotlib或Echarts生成图表。 示例代码部分,需要确保语法正确,特别是PySpark的部分。比如,数据读取、预处理、模型训练、实时处理的代码片段。同时,要注意代码的注释和解释,让用户能理解每一步的作用。 可能用户还不太清楚如何将各个模块整合起来,所以需要给出一个系统架构图,并分步骤讲解。此外,用户可能关心性能优化,比如调整Spark的配置参数,使用缓存机制,或者分区策略来提高处理速度。 最后,相关问题部分,需要根据内容生成相关问题,比如如何优化Spark作业、如何选择情感分析模型、如何处理实时数据延迟等。这些问题需要与用户的实际应用场景相关,帮助他们深入理解系统构建的细节。 总结一下,回答需要分步骤,从架构设计到各个模块的实现,提供代码示例,并引用相关的参考文献来支持建议。同时,确保使用正确的中文术语和LaTeX格式,比如数学公式的呈现。</think>### 基于Spark的哩数据情感分析系统构建教程 #### 一、系统架构设计 系统分为以下模块(参考引用[1][3][4]): 1. **数据采集**:通过BAPI或爬虫获取弹幕、评论、视频元数据 2. **数据预处理**:清洗、分词、特征提取 3. **情感分析模型**:基于Spark MLlib或预训练NLP模型 4. **实时趋势分析**:利用Spark Streaming生成情感趋势图(引用[1][3]) 5. **可视化展示**:通过Web应用展示情感分布(引用[1]) #### 二、核心实现步骤 ##### 1. 数据采集(Python示例) ```python import requests def fetch_bili_comments(bvid): url = f"https://api.bilibili.com/x/v2/reply?jsonp=jsonp&type=1&oid={bvid}" return requests.get(url).json()["data"]["replies"] ``` ##### 2. Spark预处理(PySpark) ```python from pyspark.sql import SparkSession from pyspark.sql.functions import udf import jieba spark = SparkSession.builder.appName("SentimentAnalysis").getOrCreate() # 加载原始数据 raw_df = spark.read.json("hdfs://bili_comments/*.json") # 中文分词UDF @udf("array<string>") def seg_text(text): return list(jieba.cut(text)) processed_df = raw_df.select( "bvid", seg_text("content").alias("words"), "ctime" ) ``` ##### 3. 情感分析模型训练 ```python from pyspark.ml import Pipeline from pyspark.ml.feature import HashingTF, IDF from pyspark.ml.classification import LogisticRegression # 构建分类管道 tf = HashingTF(inputCol="words", outputCol="rawFeatures") idf = IDF(inputCol="rawFeatures", outputCol="features") lr = LogisticRegression(maxIter=10) pipeline = Pipeline(stages=[tf, idf, lr]) # 加载标注数据(示例) training_df = spark.read.parquet("labeled_data.parquet") model = pipeline.fit(training_df) ``` ##### 4. 实时分析(Spark Structured Streaming) ```python from pyspark.sql.types import * schema = StructType([ StructField("content", StringType()), StructField("timestamp", TimestampType()) ]) stream_df = spark.readStream \ .format("kafka") \ .option("kafka.bootstrap.servers", "localhost:9092") \ .option("subscribe", "bili_comments") \ .load() # 实时预测 predicted_stream = model.transform( stream_df.selectExpr("CAST(value AS STRING)").select(from_json("value", schema).alias("data")) ) ``` #### 三、可视化部署 使用Flask+ECharts展示结果(引用[1][2]): ```python from flask import Flask, render_template from pyspark.sql import SparkSession app = Flask(__name__) @app.route("/trend") def show_trend(): spark = SparkSession.builder.getOrCreate() df = spark.sql("SELECT hour(ctime) as h, avg(sentiment) FROM comments GROUP BY h") return render_template("trend.html", data=df.collect()) ``` #### 四、优化建议 1. **分布式分词**:使用jieba的并行分词模式加速处理 2. **模型缓存**:对训练好的模型使用`persist()`方法(引用[4]) 3. **动态资源分配**:配置`spark.dynamicAllocation.enabled=true`
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值