基于Python+大数据的线上教育平台数据分析系统设计与实现

💗博主介绍:✌全网粉丝10W+,CSDN全栈领域优质创作者,博客之星、掘金/华为云/阿里云等平台优质作者。
👇🏻 精彩专栏 推荐订阅👇🏻
计算机毕业设计精品项目案例-200套
🌟文末获取源码+数据库+文档🌟
感兴趣的可以先收藏起来,还有大家在毕设选题,项目以及论文编写等相关问题都可以和学长沟通,希望帮助更多的人

一.前言

在这里插入图片描述

随着互联网技术的不断和快速发展,网络与大数据很早就成为了人们生活中的一部分,线上教育平台大数据分析由于其特有的便捷性,用户能够更加容易地接受。互联网有了这种便捷调剂信息(阅读量TOP10)、访问信息等分析形式,也是一种新型的全新应用形式[3]。从侧面来看,线上教育平台大数据分析还能够推进网上用户查看爬取下的大数据调剂信息的普及。
同传统的人工统计数据模式相比,线上教育平台大数据分析具有较多的优势。建立规范化的流程通常可以解决用户查询阅读量统计、发布时间统计、地区访问量统计、访问类型统计、调剂信息(阅读量TOP10)分析问题,而目前如果需要管理网站爬取下的大数据,管理员依然以人工的方式进行管理的话太过于落后。线上教育平台大数据分析处理数据越来越趋于信息化,这种模式需要依赖于智能化手段管理。随着科技发展的进步与大数据的普及,信息技术能够改善我们的生活,现在许多生活场景都需要信息化技术帮助改善我们的生活。
本课题就是以线上教育系统爬取为例,介绍网络爬虫的基本原理,Python环境的搭建,PyCharm scrapy模块的爬虫数据的运用,把获取到的数据进行清洗、整合,储存数据到MySQL,然后进行数据可视化的呈现,简单对呈现的图进行数据分析。


二.技术环境

开发语言:Python
python框架:django
软件版本:python3.7/python3.8
数据库:mysql 5.7或更高版本
数据库工具:Navicat11
爬虫框架:Scrapy
开发软件:PyCharm/vs code
前端框架:vue.js


三.功能设计

系统功能结构图是系统设计阶段,系统功能结构图只是这个阶段一个基础,整个系统的架构决定了系统的整体模式,是系统的根据。线上教育平台数据分析系统的整个设计结构如图所示。
在这里插入图片描述

四.数据设计

概念模型的设计是为了抽象真实世界的信息,并对信息世界进行建模。它是数据库设计的强大工具。数据库概念模型设计可以通过E-R图描述现实世界的概念模型。系统的E-R图显示了系统中实体之间的链接。而且Mysql数据库是自我保护能力比较强的数据库,下图主要是对数据库实体的E-R图:
在这里插入图片描述

在这里插入图片描述

五.部分效果展示

系统管理员功能实现效果

管理员要登录线上教育平台大数据分析,需要输入账号和密码,进行登录,管理员登录界面如图所示。

在这里插入图片描述

管理员登录进入线上教育平台大数据分析可以查看系统首页、个人中心、调剂信息管理、访问信息管理、访问类型管理、系统管理等功能,进行详细操作,如图所示。
在这里插入图片描述

管理员点击调剂信息管理;在调剂信息管理页面输入来源、学校名、标题、阅读量、发布时间、分类等信息,进行查询,爬起数据或删除调剂信息等操作;如图所示。

在这里插入图片描述

管理员点击访问信息管理;在访问信息管理页面输入访问编号、访问地区、访问量、访问类型、更新时间等信息,进行查询,新增、导入或删除访问信息等操作;如图所示。

在这里插入图片描述

管理员点击访问类型管理;在访问类型管理页面输入访问类型等信息,进行查询、新增或删除访问类型等操作;如图所示。
在这里插入图片描述

管理员点击系统管理;在系统管理页面对系统简介等信息,进行查询或修改系统信息等操作;如图所示。
在这里插入图片描述

数据可视化分析大屏展示实现效果

线上教育平台分析系统展示图,如图所示。

在这里插入图片描述

下面展示是阅读量统计,对于阅读量统计大数据,数据获取之后,开始对这些数据进行可视化分析,首先是阅读量统计的基本情况,其中根据爬取的数据以饼状图的形式来展示,如图所示。
在这里插入图片描述

下面展示是发布时间统计,对于发布时间统计大数据获取之后,开始对这些数据进行可视化分析,首先通过页面查看发布时间统计详情进行展示,如图所示。
在这里插入图片描述

在地区访问量统计页面以条形图进行展示所示。

在这里插入图片描述

下图是访问类型统计,通过python爬取清洗后的数据以饼状图形式展示如图所示:
在这里插入图片描述

下图是调剂信息(阅读量TOP10),通过python爬取清洗后的数据以信息表形式展示如图所示:

在这里插入图片描述

六.部分功能代码

# 数据爬取文件

import scrapy
import pymysql
import pymssql
from ..items import TiaojixinxiItem
import time
import re
import random
import platform
import json
import os
from urllib.parse import urlparse
import requests
import emoji

# 调剂信息
class TiaojixinxiSpider(scrapy.Spider):
    name = 'tiaojixinxiSpider'
    spiderUrl = 'http://jixun.iqihang.com/schoolkytj/index.html'
    start_urls = spiderUrl.split(";")
    protocol = ''
    hostname = ''

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

    def start_requests(self):

        plat = platform.system().lower()
        if plat == 'linux' or plat == 'windows':
            connect = self.db_connect()
            cursor = connect.cursor()
            if self.table_exists(cursor, 'qh73g_tiaojixinxi') == 1:
                cursor.close()
                connect.close()
                self.temp_data()
                return

        pageNum = 1 + 1
        for url in self.start_urls:
            if '{}' in url:
                for page in range(1, pageNum):
                    next_link = url.format(page)
                    yield scrapy.Request(
                        url=next_link,
                        callback=self.parse
                    )
            else:
                yield scrapy.Request(
                    url=url,
                    callback=self.parse
                )

    # 列表解析
    def parse(self, response):
        
        _url = urlparse(self.spiderUrl)
        self.protocol = _url.scheme
        self.hostname = _url.netloc
        plat = platform.system().lower()
        if plat == 'windows_bak':
            pass
        elif plat == 'linux' or plat == 'windows':
            connect = self.db_connect()
            cursor = connect.cursor()
            if self.table_exists(cursor, 'qh73g_tiaojixinxi') == 1:
                cursor.close()
                connect.close()
                self.temp_data()
                return

        list = response.css('div.listLeft ul li')
        
        for item in list:

            fields = TiaojixinxiItem()



            fields["laiyuan"] = self.remove_html(item.css('a::attr(href)').extract_first())
            if fields["laiyuan"].startswith('//'):
                fields["laiyuan"] = self.protocol + ':' + fields["laiyuan"]
            elif fields["laiyuan"].startswith('/'):
                fields["laiyuan"] = self.protocol + '://' + self.hostname + fields["laiyuan"]
            fields["xuexiaoming"] = self.remove_html(item.css('a span::text').extract_first())
            fields["biaoti"] = self.remove_html(item.css('a span:nth-child(2)::text').extract_first())
            fields["fabushijian"] = self.remove_html(item.css('a span:nth-child(3)::text').extract_first())

            detailUrlRule = item.css('a::attr(href)').extract_first()
            if self.protocol in detailUrlRule:
                pass
            elif detailUrlRule.startswith('//'):
                detailUrlRule = self.protocol + ':' + detailUrlRule
            else:
                detailUrlRule = self.protocol + '://' + self.hostname + detailUrlRule
                fields["laiyuan"] = detailUrlRule

            yield scrapy.Request(url=detailUrlRule, meta={'fields': fields},  callback=self.detail_parse, dont_filter=True)


    # 详情解析
    def detail_parse(self, response):
        fields = response.meta['fields']

        try:
            if '(.*?)' in '''div[class="rt time"] p:nth-child(4)::text''':
                fields["yueduliang"] = re.findall(r'''div[class="rt time"] p:nth-child(4)::text''', response.text, re.S)[0].strip()
            else:
                if 'yueduliang' != 'xiangqing' and 'yueduliang' != 'detail' and 'yueduliang' != 'pinglun' and 'yueduliang' != 'zuofa':
                    fields["yueduliang"] = self.remove_html(response.css('''div[class="rt time"] p:nth-child(4)::text''').extract_first())
                else:
                    fields["yueduliang"] = emoji.demojize(response.css('''div[class="rt time"] p:nth-child(4)::text''').extract_first())
        except:
            pass


        try:
            if '(.*?)' in '''div[class="lt time"] p:nth-child(2)::text''':
                fields["fenlei"] = re.findall(r'''div[class="lt time"] p:nth-child(2)::text''', response.text, re.S)[0].strip()
            else:
                if 'fenlei' != 'xiangqing' and 'fenlei' != 'detail' and 'fenlei' != 'pinglun' and 'fenlei' != 'zuofa':
                    fields["fenlei"] = self.remove_html(response.css('''div[class="lt time"] p:nth-child(2)::text''').extract_first())
                else:
                    fields["fenlei"] = emoji.demojize(response.css('''div[class="lt time"] p:nth-child(2)::text''').extract_first())
        except:
            pass


        try:
            if '(.*?)' in '''div.art_content''':
                fields["detail"] = re.findall(r'''div.art_content''', response.text, re.S)[0].strip()
            else:
                if 'detail' != 'xiangqing' and 'detail' != 'detail' and 'detail' != 'pinglun' and 'detail' != 'zuofa':
                    fields["detail"] = self.remove_html(response.css('''div.art_content''').extract_first())
                else:
                    fields["detail"] = emoji.demojize(response.css('''div.art_content''').extract_first())
        except:
            pass




        return fields

    # 去除多余html标签
    def remove_html(self, html):
        if html == None:
            return ''
        pattern = re.compile(r'<[^>]+>', re.S)
        return pattern.sub('', html).strip()

    # 数据库连接
    def db_connect(self):
        type = self.settings.get('TYPE', 'mysql')
        host = self.settings.get('HOST', 'localhost')
        port = int(self.settings.get('PORT', 3306))
        user = self.settings.get('USER', 'root')
        password = self.settings.get('PASSWORD', '123456')

        try:
            database = self.databaseName
        except:
            database = self.settings.get('DATABASE', '')

        if type == 'mysql':
            connect = pymysql.connect(host=host, port=port, db=database, user=user, passwd=password, charset='utf8')
        else:
            connect = pymssql.connect(host=host, user=user, password=password, database=database)

        return connect

    # 断表是否存在
    def table_exists(self, cursor, table_name):
        cursor.execute("show tables;")
        tables = [cursor.fetchall()]
        table_list = re.findall('(\'.*?\')',str(tables))
        table_list = [re.sub("'",'',each) for each in table_list]

        if table_name in table_list:
            return 1
        else:
            return 0

    # 数据缓存源
    def temp_data(self):

        connect = self.db_connect()
        cursor = connect.cursor()
        sql = '''
            insert into tiaojixinxi(
                laiyuan
                ,xuexiaoming
                ,biaoti
                ,fabushijian
                ,yueduliang
                ,fenlei
                ,detail
            )
            select
                laiyuan
                ,xuexiaoming
                ,biaoti
                ,fabushijian
                ,yueduliang
                ,fenlei
                ,detail
            from qh73g_tiaojixinxi
            where(not exists (select
                laiyuan
                ,xuexiaoming
                ,biaoti
                ,fabushijian
                ,yueduliang
                ,fenlei
                ,detail
            from tiaojixinxi where
             tiaojixinxi.laiyuan=qh73g_tiaojixinxi.laiyuan
            and tiaojixinxi.xuexiaoming=qh73g_tiaojixinxi.xuexiaoming
            and tiaojixinxi.biaoti=qh73g_tiaojixinxi.biaoti
            and tiaojixinxi.fabushijian=qh73g_tiaojixinxi.fabushijian
            and tiaojixinxi.yueduliang=qh73g_tiaojixinxi.yueduliang
            and tiaojixinxi.fenlei=qh73g_tiaojixinxi.fenlei
            and tiaojixinxi.detail=qh73g_tiaojixinxi.detail
            ))
            limit {0}
        '''.format(random.randint(20,30))

        cursor.execute(sql)
        connect.commit()

        connect.close()


最后

最新计算机毕业设计选题篇-选题推荐(值得收藏)
计算机毕业设计精品项目案例-200套(值得订阅)

### 在线教育平台数据分析系统架构设计 #### 1. 架构概述 为了有效管理和分析在线教育平台积累的大规模数据,采用了一种分层次的数据仓库架构。该架构不仅能够处理大量的历史数据和实时数据,还能支持复杂的数据查询和分析操作。通过引入大数据技术和分布式计算框架,可以显著提升数据处理效率并降低延迟。 #### 2. 技术栈选择 针对上述提到的企业面临的三个主要挑战——即大规模数据存储、跨多个异构源集成以及高效能的统计分析能力不足等问题,解决方案采用了如下关键技术: - **Hadoop生态系统**:作为底层基础设施来承载海量非结构化/半结构化的原始日志文件和其他形式的教学资源素材; - **Apache Spark**:用于执行快速迭代式的ETL过程(Extract, Transform, Load),同时也能很好地适应机器学习算法训练的需求; - **Hive/Presto**:提供了SQL接口使得分析师可以直接访问存放在HDFS上的表单视图来进行交互式探索性研究; - **Flink**:实现了流式数据处理引擎,适用于需要即时响应的应用场景比如直播课堂互动反馈等; - **Kylin/Doris**:构建高性能OLAP立方体加速报表生成速度; - **Superset/Tableau**:最终呈现给用户的可视化仪表盘界面[^2]。 ```python from pyspark.sql import SparkSession spark = SparkSession.builder \ .appName("OnlineEducationDataAnalysis") \ .config("spark.some.config.option", "some-value") \ .getOrCreate() df = spark.read.json("/path/to/data") # Perform transformations and actions using DataFrame API or SQL queries here. ``` #### 3. 数据流转路径 整个系统的运作流程大致分为以下几个阶段: - 收集来自各个渠道的学习者活动记录以及其他关联信息至集中式存储库内; - 经过清洗转换之后加载到目标位置等待后续加工处理; - 基于特定业务规则创建维度事实型表格体系以便更方便地开展高级别的聚合运算; - 利用专门优化过的MPP数据库产品加快查询性能从而缩短报告周期时间; - 将结果输出成易于理解的形式供管理层审阅参考做出相应调整措施。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一点毕设

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值