基于Python+爬虫的网络舆情分析监控系统设计与实现

💗博主介绍:✌全网粉丝15W+,CSDN全栈领域优质创作者,博客之星、掘金/知乎/b站/华为云/阿里云等平台优质作者、专注于Java、小程序/APP、python、大数据等技术领域和毕业项目实战,以及程序定制化开发、文档编写、答疑辅导等。
👇🏻 精彩专栏 推荐订阅👇🏻
计算机毕业设计精品项目案例(持续更新)
🌟文末获取源码+数据库+文档🌟
感兴趣的可以先收藏起来,还有大家在毕设选题,项目以及论文编写等相关问题都可以和学长沟通,希望帮助更多的人

一.前言

在这里插入图片描述

网络舆情分享监控系统是一款先进的工具,旨在实时监测和分析互联网上的舆论动态。该系统利用强大的爬虫技术从各种网络资源中获取数据,然后通过文本挖掘算法对数据进行深入处理和分析,以揭示网络上的热点话题、情感倾向和关键信息。管理员可以通过系统主页管理和监控用户信息,确保系统的高效运行。用户则能够访问自己的主页,查看和管理个人信息,同时浏览爬取到的网络舆情数据,了解公众对于特定话题的看法和态度。该系统提供了全面而准确的网络舆情分析,帮助企业和组织更好地理解公众对其产品和服务的观点,从而做出明智的决策和调整。无论是对于企业的市场推广,还是对于政府的社会管理,这个系统都具有重要的应用价值。

系统采用B/S架构,Python语言作为主要开发语言,MySQL技术创建和管理数据库。通过系统,管理员使用日常浏览器即可随时完成网络舆情信息发布,契合网络舆情监控管理对时效性需求的同时提高工作效率。最终,根据各个功能模块的测试结果可知网络舆情监控系统功能基本完善。


二.技术环境

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


三.功能设计

网络舆情分享监控系统的功能需求分析如下:
1.数据爬取:系统需要具备强大的网络爬虫功能,能够自动从各大社交媒体平台、新闻网站和论坛等网络资源中实时爬取数据。
2.数据处理:系统需要能够处理海量数据,包括数据清洗、去重和格式转换等操作,以便后续分析。
3.数据分析:系统需要提供数据分析功能,包括数据统计、可视化展示和趋势预测等,以便用户了解网络舆情的整体情况和发展趋势。
4.报警机制:系统需要具备预警机制,能够根据用户设定的关键词或阈值,及时发送警报通知用户。
6.用户管理:系统需要提供用户管理功能,包括用户注册、登录、权限分配等操作,以保证系统的安全性和可靠性。
系统的建设可以为网络舆情监控管理提供帮助,通过对一些基础信息管理实现针对性的安排,可以按照用户的角色权限使不同用户角色看到不一样的信息界面。现根据需求阶段的分析,我们可以大致确定系统需要包含的功能如下图所示:
在这里插入图片描述

四.数据设计

概念模型的设计是为了抽象真实世界的信息,并对信息世界进行建模。它是数据库设计的强大工具。数据库概念模型设计可以通过E-R图描述现实世界的概念模型,使用 Vision 绘制的本系统总体E-R图如下所示。

在这里插入图片描述

五.部分效果展示

5.1管理员功能实现效果

在注册流程中,用户在Vue前端填写必要信息(如用户名、密码等)并提交。前端将这些信息通过HTTP请求发送到Python后端。后端处理这些信息,检查用户名是否唯一,并将新用户数据存入MySQL数据库。完成后,后端向前端发送注册成功的确认,前端随后通知用户完成注册。这个过程实现了新用户的数据收集、验证和存储。如图所示。
在这里插入图片描述

管理员进入主页面,主要功能包括对主页、用户信息、用户、网络舆情、系统简介等进行操作。

用户功能实现是在Django后端部分,您需要创建一个新的应用,然后在该应用下创建一个模型(models.py)来定义用户的数据结构,使用Django的ORM来处理与MySQL数据库的交互,包括用户信息的搜索、增加或删除等操作。接着,在views.py中编写视图逻辑来处理前端请求,使用Django的URL路由(urls.py)将请求映射到相应的视图函数。对于数据的验证和序列化,可以使用Django的表单或序列化器来实现。在前端Vue.js部分,将创建相应的Vue组件,在这些组件中使用axios或其他HTTP库与Django后端的API进行交互,实现用户信息的浏览、修改或删除等。状态管理可以通过Vuex来维护,比如在store目录下定义用户模块的状态、突变、动作和获取器。如图所示:
在这里插入图片描述

网络舆情管理功能实现是在Django后端部分,您需要创建一个新的应用,然后在该应用下创建一个模型(models.py)来定义网络舆情的数据结构,使用Django的ORM来处理与MySQL数据库的交互,包括网络舆情信息的搜索、删除或爬取数据等操作。接着,在views.py中编写视图逻辑来处理前端请求,使用Django的URL路由(urls.py)将请求映射到相应的视图函数。对于数据的验证和序列化,可以使用Django的表单或序列化器来实现。在前端Vue.js部分,将创建相应的Vue组件,在这些组件中使用axios或其他HTTP库与Django后端的API进行交互,实现网络舆情信息的浏览或删除等。状态管理可以通过Vuex来维护,比如在store目录下定义网络舆情模块的状态、突变、动作和获取器。如图所示:
在这里插入图片描述

管理员进行爬取数据后可以在看板页面查看到系统简介、评论数统计、点赞数统计、分享数统计、发布城市统计、网络舆情总数、网络舆情详情等实时的分析图进行可视化管理;看板大屏选择了Echart作为数据可视化工具,它是一个使用JavaScript实现的开源可视化库,能够无缝集成到Java Web应用中。Echart的强大之处在于其丰富的图表类型和高度的定制化能力,使得管理人员可以通过直观的图表清晰地把握网络舆情的各项统计数据。
为了实现对网络舆情信息的自动化收集和更新,我们采用了Apache Spark作为爬虫技术的基础。Spark的分布式计算能力使得系统能够高效地处理大规模数据,无论是从互联网上抓取最新的网络舆情信息,还是对内部数据进行ETL(提取、转换、加载)操作,都能够保证数据的实时性和准确性。
在大数据分析方面,系统采用了Hadoop框架。Hadoop是一个能够处理大数据集的分布式存储和计算平台,它的核心是HDFS(Hadoop Distributed File System)和MapReduce计算模型。通过Hadoop,我们可以对收集到的大量数据进行存储和分析。看板页面如图所示:
在这里插入图片描述

管理员点击系统简介,在系统简介页面输入标题进行搜索,可以查看到系统简介详细信息,并根据需要进行浏览或修改操作。如图所示:
在这里插入图片描述

5.2用户功能实现效果

用户进入主页面,主要功能包括对主页、用户信息、网络舆情等进行操作。用户主页面如图所示:

在这里插入图片描述

用户点击网络舆情,进入网络舆情页面输入博主和发布城市进行搜索网络舆情详细信息。并进行浏览操作。如图所示:

在这里插入图片描述

六.部分功能代码

# # -*- coding: utf-8 -*-

# # -*- coding: utf-8 -*-

# 数据爬取文件

import scrapy
import pymysql
import pymssql
from ..items import WangluoyuqingItem
import time
from datetime import datetime,timedelta
import datetime as formattime
import re
import random
import platform
import json
import os
import urllib
from urllib.parse import urlparse
import requests
import emoji
import numpy as np
import pandas as pd
from sqlalchemy import create_engine
from selenium.webdriver import ChromeOptions, ActionChains
from scrapy.http import TextResponse
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait
# 网络舆情
class WangluoyuqingSpider(scrapy.Spider):
    name = 'wangluoyuqingSpider'
    spiderUrl = 'https://m.weibo.cn/api/container/getIndex?containerid=100103type%3D1%26q%3D%E7%BD%91%E7%BB%9C%E8%88%86%E6%83%85&_T_WM=57111142162&v_p=42&page_type=searchall'
    start_urls = spiderUrl.split(";")
    protocol = ''
    hostname = ''
    realtime = False

    headers = {
        'Referer':'https://m.weibo.cn/search?containerid=100103type%3D1%26q%3D%E7%BD%91%E7%BB%9C%E8%88%86%E6%83%85&_T_WM=57111142162&v_p=42',
'Cookie':'用自己的Cookie'
    }

    def __init__(self,realtime=False,*args, **kwargs):
        super().__init__(*args, **kwargs)
        self.realtime = realtime=='true'

    def start_requests(self):

        plat = platform.system().lower()
        if not self.realtime and (plat == 'linux' or plat == 'windows'):
            connect = self.db_connect()
            cursor = connect.cursor()
            if self.table_exists(cursor, '792099hc_wangluoyuqing') == 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,
                        headers=self.headers,
                        callback=self.parse
                    )
            else:
                yield scrapy.Request(
                    url=url,
                    headers=self.headers,
                    callback=self.parse
                )

    # 列表解析
    def parse(self, response):
        _url = urlparse(self.spiderUrl)
        self.protocol = _url.scheme
        self.hostname = _url.netloc
        plat = platform.system().lower()
        if not self.realtime and (plat == 'linux' or plat == 'windows'):
            connect = self.db_connect()
            cursor = connect.cursor()
            if self.table_exists(cursor, '792099hc_wangluoyuqing') == 1:
                cursor.close()
                connect.close()
                self.temp_data()
                return
        data = json.loads(response.body)
        try:
            list = data["data"]["cards"]
        except:
            pass
        for item in list:
            fields = WangluoyuqingItem()


            try:
                fields["author"] = emoji.demojize(self.remove_html(str( item["card_group"][0]["mblog"]["user"]["screen_name"] )))

            except:
                pass
            try:
                fields["text"] = emoji.demojize(self.remove_html(str( item["card_group"][0]["mblog"]["text"] )))

            except:
                pass
            try:
                fields["bozhuinfo"] = emoji.demojize(self.remove_html(str( item["card_group"][0]["mblog"]["user"]["description"] )))

            except:
                pass
            try:
                fields["comments"] = int( item["card_group"][0]["mblog"]["comments_count"])
            except:
                pass
            try:
                fields["attitudes"] = int( item["card_group"][0]["mblog"]["attitudes_count"])
            except:
                pass
            try:
                fields["reposts"] = int( item["card_group"][0]["mblog"]["reposts_count"])
            except:
                pass
            try:
                fields["city"] = emoji.demojize(self.remove_html(str( item["card_group"][0]["mblog"]["status_city"] )))

            except:
                pass
            try:
                fields["detailurl"] = emoji.demojize(self.remove_html(str( item["card_group"][0]["scheme"] )))

            except:
                pass
            yield fields

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

    # 数据清洗
    def pandas_filter(self):
        engine = create_engine('mysql+pymysql://root:123456@localhost/spider792099hc?charset=UTF8MB4')
        df = pd.read_sql('select * from wangluoyuqing limit 50', con = engine)

        # 重复数据过滤
        df.duplicated()
        df.drop_duplicates()

        #空数据过滤
        df.isnull()
        df.dropna()

        # 填充空数据
        df.fillna(value = '暂无')

        # 异常值过滤

        # 滤出 大于800 和 小于 100 的
        a = np.random.randint(0, 1000, size = 200)
        cond = (a<=800) & (a>=100)
        a[cond]

        # 过滤正态分布的异常值
        b = np.random.randn(100000)
        # 3σ过滤异常值,σ即是标准差
        cond = np.abs(b) > 3 * 1
        b[cond]

        # 正态分布数据
        df2 = pd.DataFrame(data = np.random.randn(10000,3))
        # 3σ过滤异常值,σ即是标准差
        cond = (df2 > 3*df2.std()).any(axis = 1)
        # 不满⾜条件的⾏索引
        index = df2[cond].index
        # 根据⾏索引,进⾏数据删除
        df2.drop(labels=index,axis = 0)

    # 去除多余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 `wangluoyuqing`(
                id
                ,author
                ,text
                ,bozhuinfo
                ,comments
                ,attitudes
                ,reposts
                ,city
                ,detailurl
            )
            select
                id
                ,author
                ,text
                ,bozhuinfo
                ,comments
                ,attitudes
                ,reposts
                ,city
                ,detailurl
            from `792099hc_wangluoyuqing`
            where(not exists (select
                id
                ,author
                ,text
                ,bozhuinfo
                ,comments
                ,attitudes
                ,reposts
                ,city
                ,detailurl
            from `wangluoyuqing` where
                `wangluoyuqing`.id=`792099hc_wangluoyuqing`.id
            ))
            order by rand()
            limit 50;
        '''

        cursor.execute(sql)
        connect.commit()
        connect.close()


源码及文档获取

文章下方名片联系我即可~
大家点赞、收藏、关注、评论啦 、查看👇🏻获取联系方式👇🏻
精彩专栏推荐订阅:在下方专栏👇🏻

最新计算机毕业设计选题篇-选题推荐
小程序毕业设计精品项目案例-200套
Java毕业设计精品项目案例-200套
Python毕业设计精品项目案例-200套
大数据毕业设计精品项目案例-200套
💟💟如果大家有任何疑虑,欢迎在下方位置详细交流。

  • 24
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

一点毕设

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

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

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

打赏作者

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

抵扣说明:

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

余额充值