【有源码】基于python+爬虫的新闻数据分析及可视化系统

注意:该项目只展示部分功能,如需了解,文末咨询即可。

本文目录

  • 1.开发环境
  • 2 系统设计
  • 2.1 设计背景
  • 2.2 设计内容
  • 3 系统页面展示
  • 3.3 功能展示视频
  • 4 更多推荐
  • 5 爬虫代码
  • 1.开发环境

    开发语言:Python
    技术框架:Django、爬虫
    数据库:MySQL
    开发工具:PyCharm

    2 系统设计

    2.1 设计背景

    随着社会的飞速发展,新闻产业也在不断的发展,对新闻的数量、种类、质量等提出了越来越高的需求,这也使得网络的经营与经营变得越来越困难。科技的革新极大地改变了人类的生活,改变了人们的衣食住行,也改变了人们获取信息的途径。首先有人发明了报纸,人们可以通过它获得新闻,再后来,电视和互联网的出现,改变了人们阅读信息的方式,如今,人们获得新闻的渠道变得更加方便,也更加多样化,现代社会的网络和信息技术得到了长足的发展,人民的生活质量也得到了极大的提升。然而,随着工作、生活的繁忙,一个能让更好地利用碎片化的时间、精简流程的节目,才是最需要的。基于此,本文提出了一种快速、便捷的新闻数据分析与推荐系统。
    该新闻数据分析与推荐系统具有管理员、用户,管理员和用户两种功能,分别对用户进行信息管理,一种是管理使用者的信息,一种是使用者的租赁信息,一种是可以和使用者进行沟通的一种方式,一种是可以浏览新闻,一种是浏览新闻,一种是通过管理员的方式来实现的。该系统采用了 Django框架,以 MYSQL数据库为基础,以 B/S结构为开发平台,实现了系统的稳定运行。该系统界面清晰,操作简便,功能完善,为新闻推荐系统的管理提供了一条有效的途径。

    2.2 设计内容

    本课题旨在开发一个基于python的新闻数据分析及可视化,该系统利用Scrapy爬虫技术从新闻头条爬取相关新闻数据,然后通过Python和Spark技术进行数据处理和清理,最终存储到MySQL数据库中。系统的核心功能包括新闻评论分析、新闻点赞数量分析、新闻媒体分析、新闻转发数量分析、新闻总数分析、词云等。所有这些功能都通过Echarts可视化框架以图形的方式展现,同时,系统还提供用户管理和登录功能,为管理员和用户提供不同的操作权限和数据展示。
    1. 技术实现
    1.1 爬取新闻数据
    Scrapy框架: 使用Scrapy构建新闻数据爬虫。Scrapy是一个强大的Python爬虫框架,能够高效地提取网页数据。需要设计合理的爬虫规则,解析新闻标题、内容、评论数、点赞数、转发数等信息。
    数据存储: 将爬取的数据存储到MySQL数据库中。需要设计数据库表结构,以便高效存储和查询新闻数据。
    1.2 数据处理与清理
    Python与Spark: 使用Python脚本和Apache Spark进行大规模数据处理。Python可以用于数据预处理、清洗和格式化,Spark则可用于处理大数据集,提高数据处理效率。
    数据清理: 处理缺失值、重复数据和格式不一致的问题。数据清洗是数据分析的基础,确保分析结果的准确性和可靠性。
    1.3 数据存储
    MySQL数据库: 设计数据库表(如新闻信息表、评论表、点赞记录表等),实现数据的持久化存储。确保数据的安全性和完整性。
    2. 数据分析方法
    2.1 新闻评论分析

    评论趋势分析: 统计不同时间段、不同新闻的评论量,分析评论趋势和变化规律。
    2.2 新闻点赞数量分析
    点赞数量统计: 计算每条新闻的点赞数量,分析点赞量与新闻内容、发布时间等因素的关系。
    点赞趋势分析: 分析点赞量随时间的变化趋势,发现热点新闻和用户关注点。
    2.3 新闻媒体分析
    媒体分布: 统计新闻来源的分布情况,分析不同媒体的报道频率和偏向。
    媒体影响力分析: 通过点赞数、评论数等指标评估不同媒体的影响力。
    2.4 新闻转发数量分析
    转发数量统计: 计算每条新闻的转发数量,分析转发量与新闻内容、时间等因素的关系。
    转发趋势分析: 分析转发量随时间的变化趋势,识别新闻传播热点。
    2.5 新闻总数分析
    新闻数量统计: 统计总新闻数量、不同分类新闻数量等,分析新闻覆盖面和变化趋势。
    分类分析: 根据新闻类别(如科技、政治、娱乐等)统计不同类别的新闻数量,分析新闻类型的分布情况。
    2.6 词云生成
    关键词提取: 提取新闻标题和内容中的关键词,生成词云图。使用Python的词云库(如WordCloud)来可视化关键词的频率和重要性。
    词云分析: 通过词云图识别热门话题和关键词,揭示新闻内容的核心主题。
    3. 可视化效果
    3.1 Echarts框架

    数据展示: 使用Echarts框架对新闻数据进行可视化。Echarts支持多种图表类型(如柱状图、饼图、折线图、散点图等),可以用于展示新闻数据的各种分析结果。
    交互式图表: 提供用户交互功能,如图表缩放、数据筛选等,提升用户体验。
    3.2 可视化类型
    评论分析图表: 使用曲线图展示评论数量和情感分析结果。
    点赞数量图表: 使用柱状图展示每条新闻的点赞数量,或使用折线图分析点赞趋势。
    媒体分析图表: 使用条形图展示新闻来源的分布情况。
    转发数量图表: 使用柱状图展示新闻转发数量,或使用折线图分析转发趋势。
    词云图: 生成新闻内容的词云图,直观展示关键词的频率和重要性。
    4. 用户管理和登录功能
    4.1 用户管理

    用户角色: 设计系统用户角色(如管理员、普通用户)和权限管理。管理员可以进行数据管理和系统设置,普通用户可以查看和分析数据。
    用户信息存储: 在MySQL数据库中存储用户信息,如用户名、密码、角色等,确保用户数据的安全性。
    4.2 登录功能
    用户认证: 实现用户登录功能,包括用户名和密码验证。可以使用Python中的Django等Web框架实现用户认证功能。
    权限控制: 根据用户角色提供不同的操作权限和数据展示。确保不同用户只能访问和操作自己权限范围内的数据。

    3 系统页面展示



    3.3 功能展示视频

    基于python+爬虫的新闻数据分析与可视化系统源码

    4 更多推荐

    计算机毕设选题精选汇总
    基于Hadoop大数据电商平台用户行为分析与可视化系统
    Django+Python数据分析岗位招聘信息爬取与分析
    基于python爬虫的商城商品比价数据分析
    基于Python的网络小说榜单信息爬取与数据可视化系统
    基于Spark大数据的餐饮外卖数据分析可视化系统

    5 爬虫代码

    # # -*- coding: utf-8 -*-
    
    # 数据爬取文件
    
    import scrapy
    import pymysql
    import pymssql
    from ..items import XinwenxinxiItem
    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 XinwenxinxiSpider(scrapy.Spider):
        name = 'xinwenxinxiSpider'
        spiderUrl = 'https://m.toutiao.com/list/?tag=__all__&max_time=0&min_behot_time=0&ac=wap&count=20&format=json_raw&_signature=UhRCxwAANCPxSQ.5Mm8FWVIUQt&i=&as=A1B6F6B334C36BD&cp=6634E3D65B8D2E1&aid=1698'
        start_urls = spiderUrl.split(";")
        protocol = ''
        hostname = ''
        realtime = False
    
    
        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, 'wx07vasx_xinwenxinxi') == 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 not self.realtime and (plat == 'linux' or plat == 'windows'):
                connect = self.db_connect()
                cursor = connect.cursor()
                if self.table_exists(cursor, 'wx07vasx_xinwenxinxi') == 1:
                    cursor.close()
                    connect.close()
                    self.temp_data()
                    return
            data = json.loads(response.body)
            try:
                list = data["data"]
            except:
                pass
            for item in list:
                fields = XinwenxinxiItem()
    
    
                try:
                    fields["title"] = emoji.demojize(self.remove_html(str( item["title"] )))
    
                except:
                    pass
                try:
                    fields["picture"] = emoji.demojize(self.remove_html(str( item["image_list"][0]["url"] )))
    
                except:
                    pass
                try:
                    fields["medianame"] = emoji.demojize(self.remove_html(str( item["media_name"] )))
    
                except:
                    pass
                try:
                    fields["gaishu"] = emoji.demojize(self.remove_html(str( item["abstract"] )))
    
                except:
                    pass
                try:
                    fields["pubtime"] = emoji.demojize(self.remove_html(str( item["datetime"] )))
    
                except:
                    pass
                try:
                    fields["commentcount"] = int( item["comment_count"])
                except:
                    pass
                try:
                    fields["repincount"] = int( item["repin_count"])
                except:
                    pass
                try:
                    fields["likecount"] = int( item["like_count"])
                except:
                    pass
                try:
                    fields["laiyuan"] = emoji.demojize(self.remove_html(str( item["url"] )))
    
                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/spiderwx07vasx?charset=UTF8MB4')
            df = pd.read_sql('select * from xinwenxinxi 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 `xinwenxinxi`(
                    id
                    ,title
                    ,picture
                    ,medianame
                    ,gaishu
                    ,pubtime
                    ,commentcount
                    ,repincount
                    ,likecount
                    ,laiyuan
                )
                select
                    id
                    ,title
                    ,picture
                    ,medianame
                    ,gaishu
                    ,pubtime
                    ,commentcount
                    ,repincount
                    ,likecount
                    ,laiyuan
                from `wx07vasx_xinwenxinxi`
                where(not exists (select
                    id
                    ,title
                    ,picture
                    ,medianame
                    ,gaishu
                    ,pubtime
                    ,commentcount
                    ,repincount
                    ,likecount
                    ,laiyuan
                from `xinwenxinxi` where
                    `xinwenxinxi`.id=`wx07vasx_xinwenxinxi`.id
                ))
                order by rand()
                limit 50;
            '''
    
            cursor.execute(sql)
            connect.commit()
            connect.close()
    
    

    源码项目、定制开发、文档报告、PPT、代码答疑
    希望和大家多多交流!!

    作者:Q2643365023

    物联沃分享整理
    物联沃-IOTWORD物联网 » 【有源码】基于python+爬虫的新闻数据分析及可视化系统

    发表回复