💗博主介绍:✌全网粉丝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()