💕💕作者:计算机源码社
💕💕个人简介:本人 八年开发经验,擅长Java、Python、PHP、.NET、Node.js、Android、微信小程序、爬虫、大数据、机器学习等,大家有这一块的问题可以一起交流!
💕💕学习资料、程序开发、技术解答、文档报告
💕💕如需要源码,可以扫取文章下方二维码联系咨询
💕💕Java项目
💕💕微信小程序项目
💕💕Android项目
💕💕Python项目
💕💕PHP项目
💕💕ASP.NET项目
💕💕Node.js项目
💕💕选题推荐
项目实战|python零食销售数据分析系统食品销量分析可视化
文章目录
1、选题背景
随着互联网的发展,电子商务平台已成为消费者购买零食的重要渠道之一。尤其是在中国,像京东这样的电商平台聚集了大量的零食销售数据,这些数据对于市场分析、商业决策以及消费者行为研究具有重要意义。然而,面对如此庞大的数据量,手动获取和分析这些数据效率低下且容易出错。因此,开发一套基于Python的零食销售数据采集与可视化分析系统,可以有效地解决数据采集和分析的困难,使企业能够更准确地把握市场趋势。
2、研究目的和意义
基于python的零食销售数据采集与可视化分析系统旨在通过Scrapy爬虫技术从京东平台自动化采集零食销售数据,并将这些数据经过清洗和处理后,存储在MySQL数据库中。随后,利用Django框架搭建一个Web平台,通过Echarts实现数据的可视化展示。用户可以在平台上查看零食类别、价格、产地、店铺等信息的统计分析结果,从而更好地了解市场动态,支持管理层做出科学决策。系统还将具备用户登录、零食信息管理及用户信息管理等功能,提供全方位的数据管理与分析支持。
该系统不仅能够大幅提升零食销售数据的采集和分析效率,还能通过可视化手段,使数据的展示更加直观,帮助用户更容易地理解复杂的数据关系。对于企业而言,系统的应用能够减少人工分析的时间和成本,提高市场响应速度,并为零售商、生产商等提供有力的数据支持,从而优化供应链管理和营销策略。通过对销售数据的深入挖掘与分析,企业还能够预测未来的市场趋势和消费者需求,进一步提升竞争力。
3、系统研究内容
本系统的开发主要分为四个核心部分:数据采集、数据处理与存储、数据可视化展示以及系统功能开发。
在数据采集部分,系统采用Scrapy爬虫技术从京东平台自动化抓取与零食相关的销售数据,包括零食类别、价格、产地、店铺等详细信息。数据采集后,通过Python进行数据处理和清洗,以确保数据的准确性和一致性。清洗后的数据将被存储在MySQL数据库中,以便后续的数据分析与管理。
在数据可视化展示部分,系统利用Echarts框架,将存储在MySQL中的数据进行可视化分析和展示,系统会在大屏幕上直观地展示零食类别分布、价格区间、产地来源、店铺销售情况等多维度的数据统计分析结果。这些可视化图表不仅帮助用户快速掌握市场信息,还为企业的决策提供了重要的依据。
在系统功能开发方面,基于Python和Django框架,系统搭建了一个功能齐全的Web平台。用户可以通过该平台进行登录,管理和维护零食信息,并进行个人信息管理和用户管理等操作。系统具备友好的用户界面,支持零食数据的增删改查操作,确保数据的实时性和准确性。通过这些功能模块的有机结合,系统不仅实现了零食销售数据的全面采集和展示,还为用户提供了便捷的管理工具。
4、系统页面设计
如需要源码,可以扫取文章下方二维码联系咨询
5、参考文献
[1]冯辉,时明晶,盛建娜.数字化时代食品企业管理模式探讨[J].今日财富,2024,(19):83-85.
[2]陈正伟.数据管理与隐私计算平台的设计案例分析[J].集成电路应用,2024,41(06):220-221.DOI:10.19339/j.issn.1674-2583.2024.06.099.
[3]刘静.大数据分析在食品安全风险评估中的应用[J].食品安全导刊,2024,(12):153-156.DOI:10.16043/j.cnki.cfs.2024.12.040.
[4]何月华.食品检验中的大数据分析与质量控制[J].中国食品工业,2024,(05):65-67.
[5]金鹏,叶莉敏,孟文.大数据技术在食品安全监管中的应用分析[J].食品安全导刊,2024,(01):7-9.DOI:10.16043/j.cnki.cfs.2024.01.004.
[6]卢素珍,彭雯婧,熊铮,等.数据分析平台提升食品安全抽检效能探索[J].质量探索,2023,20(03):79-83.
[7]杨清茹.大数据技术在食品安全监管中的应用分析[J].中国食品工业,2023,(12):73-75+78.
[8]包吉.供应链实践、大数据分析对食品零售业供应链绩效的影响研究[D].吉林大学,2023. DOI:10.27162/d.cnki.gjlin.2023.005717.
[9]尚敬轩,袁田,李碧玉,等.基于C/S-B/S结构的食品水质安全快速检测信息系统设计与应用[C]//中国医学装备协会.中国医学装备大会暨2023医学装备展览会会议论文汇编.桂林联勤保障中心药品仪器监督检验站;,2023:11. DOI:10.26914/c.cnkihy.2023.018263.
[10]贾艳艳.基于数据驱动的食品安全预警体系分析与应用[J].中国食品工业,2022,(19):87-89.
[11]魏海昱,林伟鸿,贺超波.基于Scrapy的食品安全舆情数据爬取与分析[J].现代计算机,2022,28(14):49-54+95.
[12]沙勇忠,陆莉.公共安全数据协同治理的逻辑框架与网络形式------以兰州市食品安全领域为例[J].信息资源管理学报,2022,12(03):7-20.DOI:10.13365/j.jirm.2022.03.007.
[13]朱菲,陈祖满,周静峰.基于信息化数据分析的《食品专业英语》线上线下混合式"金课"的建设[J].食品与发酵科技,2022,58(02):162-166.
[14]刘然,程曼.基于数据挖掘的校园食品安全事件分析[J].电脑与电信,2022,(04):65-68.DOI:10.15966/j.cnki.dnydx.2022.04.021.
[15]赵有东,申笑颜.防控生态中食品领域大数据的应用分析[J].中国信息化,2022,(01):88-89.
[16]赵先德,唐方方.区块链赋能供应链[M].中国人民大学出版社:202201.202.
[17]腾克,王震.数据挖掘在进口食品质量安全检测中的运用分析[J].当代化工研究,2021,(20):47-48.
[18]王庆春,基于食品安全突发事件应急处理的数据关系构建与关联分析方法研究.北京市,国家市场监督管理总局信息中心,2021-09-28.
[19]沈力.大数据背景下计算机技术在食品安全管理中的运用分析[J].食品安全导刊,2021,(24):184-185.DOI:10.16043/j.cnki.cfs.2021.24.099.
[20]李丹.关于利用大数据建立食品行业的危害控制措施指导的探讨[J].食品安全质量检测学报,2021,12(12):5054-5058.DOI:10.19812/j.cnki.jfsq11-5956/ts.2021.12.050.
6、核心代码
java
# # -*- coding: utf-8 -*-
# 数据爬取文件
import scrapy
import pymysql
import pymssql
from ..items import JianfeiItem
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 JianfeiSpider(scrapy.Spider):
name = 'jianfeiSpider'
spiderUrl = 'https://search.jd.com/Search?keyword=%E5%87%8F%E8%82%A5&wq=%E5%87%8F%E8%82%A5&pvid=4ac391e8e75a42a7b69a0d9ac6efffc7&isList=0&page={}&s=56&click=0&log_id=1705715346068.8561'
start_urls = spiderUrl.split(";")
protocol = ''
hostname = ''
realtime = False
headers = {
"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, 'z6e9n865_jianfei') == 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, 'z6e9n865_jianfei') == 1:
cursor.close()
connect.close()
self.temp_data()
return
list = response.css('div.gl-i-wrap')
for item in list:
fields = JianfeiItem()
fields["title"] = ' '.join(item.xpath('''.//div[@class='p-name p-name-type-2']/a/em//text()''').extract())
try:
fields["picture"] = str("https:"+ item.xpath('''.//div[@class='p-img']/a/img/@data-lazy-img''').extract()[0].strip())
except:
pass
if '(.*?)' in '''div.p-price i::text''':
try:
fields["price"] = float( re.findall(r'''div.p-price i::text''', item.extract(), re.DOTALL)[0].strip())
except:
pass
else:
try:
fields["price"] = float( self.remove_html(item.css('div.p-price i::text').extract_first()))
except:
pass
if '(.*?)' in '''span.J_im_icon>a::text''':
try:
fields["dianpu"] = str( re.findall(r'''span.J_im_icon>a::text''', item.extract(), re.DOTALL)[0].strip())
except:
pass
else:
try:
fields["dianpu"] = str( self.remove_html(item.css('''span.J_im_icon>a::text''').extract_first()))
except:
pass
if '(.*?)' in '''div.p-img a::attr(href)''':
try:
fields["laiyuan"] = str("https:"+ re.findall(r'''div.p-img a::attr(href)''', item.extract(), re.DOTALL)[0].strip())
except:
pass
else:
try:
fields["laiyuan"] = str("https:"+ self.remove_html(item.css('''div.p-img a::attr(href)''').extract_first()))
except:
pass
detailUrlRule = item.css('div.p-img a::attr(href)').extract_first()
if self.protocol in detailUrlRule or detailUrlRule.startswith('http'):
pass
elif detailUrlRule.startswith('//'):
detailUrlRule = self.protocol + ':' + detailUrlRule
elif detailUrlRule.startswith('/'):
detailUrlRule = self.protocol + '://' + self.hostname + detailUrlRule
else:
detailUrlRule = self.protocol + '://' + self.hostname + '/' + detailUrlRule
yield scrapy.Request(url=detailUrlRule, meta={'fields': fields}, headers=self.headers, callback=self.detail_parse, dont_filter=True)
# 详情解析
def detail_parse(self, response):
fields = response.meta['fields']
try:
if '(.*?)' in '''div#choose-attr-1 div.dd div::attr(data-value)''':
fields["category"] = str( re.findall(r'''div#choose-attr-1 div.dd div::attr(data-value)''', response.text, re.S)[0].strip())
else:
if 'category' != 'xiangqing' and 'category' != 'detail' and 'category' != 'pinglun' and 'category' != 'zuofa':
fields["category"] = str( self.remove_html(response.css('''div#choose-attr-1 div.dd div::attr(data-value)''').extract_first()))
else:
try:
fields["category"] = str( emoji.demojize(response.css('''div#choose-attr-1 div.dd div::attr(data-value)''').extract_first()))
except:
pass
except:
pass
try:
fields["pianhao"] = str( response.xpath('''//li[starts-with(text(), "商品编号")]/text()''').extract()[0].strip().replace("商品编号:", ""))
except:
pass
try:
fields["maozhong"] = str( response.xpath('''//li[starts-with(text(), "商品毛重")]/text()''').extract()[0].strip().replace("商品毛重:", ""))
except:
pass
try:
fields["chandi"] = str( response.xpath('''//li[starts-with(text(), "商品产地")]/text()''').extract()[0].strip().replace("商品产地:", ""))
except:
pass
try:
fields["chengfen"] = str( response.xpath('''//li[starts-with(text(), "主要成分")]/text()''').extract()[0].strip().replace("主要成分:", ""))
except:
pass
try:
if '(.*?)' in '''//li[starts-with(text(), "类别")]/text()''':
fields["leibie"] = str( re.findall(r'''//li[starts-with(text(), "类别")]/text()''', response.text, re.S)[0].strip().replace("类别:", ""))
else:
fields["leibie"] = ','.join(response.xpath('''//li[starts-with(text(), "类别")]/text()''').extract()).replace("类别:", "")
except:
pass
return fields
# 数据清洗
def pandas_filter(self):
engine = create_engine('mysql+pymysql://root:123456@localhost/spiderz6e9n865?charset=UTF8MB4')
df = pd.read_sql('select * from jianfei 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 `jianfei`(
id
,title
,picture
,price
,dianpu
,category
,pianhao
,maozhong
,chandi
,chengfen
,leibie
,laiyuan
)
select
id
,title
,picture
,price
,dianpu
,category
,pianhao
,maozhong
,chandi
,chengfen
,leibie
,laiyuan
from `z6e9n865_jianfei`
where(not exists (select
id
,title
,picture
,price
,dianpu
,category
,pianhao
,maozhong
,chandi
,chengfen
,leibie
,laiyuan
from `jianfei` where
`jianfei`.id=`z6e9n865_jianfei`.id
))
order by rand()
limit 50;
'''
cursor.execute(sql)
connect.commit()
connect.close()
💕💕作者:计算机源码社
💕💕个人简介:本人 八年开发经验,擅长Java、Python、PHP、.NET、Node.js、Android、微信小程序、爬虫、大数据、机器学习等,大家有这一块的问题可以一起交流!
💕💕学习资料、程序开发、技术解答、文档报告
💕💕如需要源码,可以扫取文章下方二维码联系咨询