Python电商数据分析系统:基于Django的爬虫、可视化与销量预测实战
2026/9/1 2:29:25 网站建设 项目流程

如果你正在做“电商数据分析”方向的课程设计、毕业设计,或者想用 Python 完整走一遍“数据采集 → 数据清洗 → 数据可视化 → 销量预测”的链路,那这个项目非常值得参考。它不是单一算法,而是一套围绕 Django 框架搭建的电商数据分析系统,覆盖了爬虫、数据分析、可视化、词云图和机器学习预测算法,属于典型的“一个项目打通多个技术栈”的练手作品。

这篇文章会先把项目的核心能力、硬件门槛和适合场景讲清楚,再拆解每个模块怎么落地。重点会放在 Django 怎么组织整个项目、爬虫数据怎么入库、分析结果怎么可视化、词云图怎么做、销量预测算法怎么接进 Web 系统,以及常见问题和排查思路。如果你更关心“这个项目到底能不能跑起来、要花多少精力改造”,这篇文章可以直接收藏。

1. 核心能力速览

能力项说明
项目类型电商数据分析 Web 系统,技术教学 / 毕设方向
技术栈Python、Django、Pandas、NumPy、Matplotlib / PyECharts、WordCloud、Scikit-learn
主要功能商品数据爬取、数据清洗与存储、数据分析可视化、评论词云图、销量预测
预测算法以机器学习回归模型为主,如线性回归、随机森林回归,可替换为时序模型
启动方式Django 自带开发服务器,命令行启动即可
显存要求无 GPU 要求,纯 CPU 可运行
支持平台Windows / Linux / macOS
是否支持 APIDjango 视图本身可作为接口访问,也可扩展 REST API
是否支持批量任务爬虫和预测模块可设计为定时任务或批量处理
适合场景课程设计、毕业设计、数据分析入门练手、小型电商运营辅助工具

从整体设计看,这个项目最大的价值在于“链路完整”。很多同学单独学爬虫能写,单独学 sklearn 能跑,但把它们组合成一个 Django Web 项目时,经常会卡在数据格式、模型序列化、前端展示这些环节。这个项目把整条链路串了起来,你替换成自己的商品数据或平台数据就能二次开发。

2. 适用场景与使用边界

这个项目适合以下几类人。

第一类是正在做课程设计或毕业设计的计算机专业学生。项目标题里的关键词——Python、Django 框架、数据分析、爬虫、机器学习——基本都是课程设计的高频选题方向。用一个系统同时覆盖这些关键词,答辩时技术点更好讲。

第二类是刚开始接触数据分析的开发者。你不需要先精通机器学习,再学 Web 开发。通过这个项目,你可以看到数据在“数据库表 → DataFrame → 图表 → 页面模板”之间的流转过程,理解起来比单独看教程更直观。

第三类是有小型电商选品或运营需求的人。比如你想定期分析某平台公开商品的销量趋势、价格区间和用户评价关键词,这套系统改造后可以做成一个内部小工具。

使用边界也要说清楚。爬虫部分只应该采集公开数据、遵守目标网站的 robots 协议和控制请求频率,不能爬取用户隐私数据,也不能对目标网站造成压力。销量预测的结果只是基于历史数据的参考,不能作为真实库存决策的唯一依据。涉及评论、用户信息等内容时,要注意脱敏和授权。WordCloud 词云图如果使用中文字体,需要额外配置字体路径,否则会显示乱码。

3. 环境准备与前置条件

环境要求不高,常规开发机都能满足。

3.1 基础环境

依赖项建议要求
操作系统Windows 10 / 11、Ubuntu 20.04+、macOS
Python 版本Python 3.8 ~ 3.11
包管理工具pip,建议使用虚拟环境
数据库SQLite(Django 默认)即可,也可切换 MySQL
开发工具VS Code、PyCharm 均可

如果你本机没有安装 Python,先去 Python 官网下载对应版本。安装时务必勾选“Add Python to PATH”,否则命令行里执行python会提示找不到命令。

推荐使用虚拟环境隔离项目依赖,避免多个项目之间的包版本冲突。在项目目录下执行:

# 创建虚拟环境 python -m venv venv # Windows 激活 venv\Scripts\activate # Linux / macOS 激活 source venv/bin/activate

3.2 安装依赖

核心依赖如下:

  • Django:Web 框架主体
  • requests / BeautifulSoup4 / Scrapy:爬虫模块
  • pandas / numpy:数据处理
  • matplotlib / pyecharts:图表可视化
  • wordcloud / jieba:词云图和中文分词
  • scikit-learn:机器学习预测算法

安装命令:

pip install django requests beautifulsoup4 pandas numpy matplotlib pyecharts wordcloud jieba scikit-learn

如果你用 Scrapy 做爬虫,可以单独安装:

pip install scrapy

3.3 目录规划建议

一个典型的 Django 项目结构可以这样组织:

ecommerce_analysis/ ├── manage.py ├── requirements.txt ├── apps/ │ ├── goods/ # 商品数据管理 │ ├── crawler/ # 爬虫相关 │ ├── analysis/ # 数据分析与可视化 │ └── prediction/ # 销量预测算法 ├── static/ │ ├── css/ │ ├── js/ │ └── images/ ├── templates/ │ ├── base.html │ ├── index.html │ ├── analysis.html │ └── prediction.html ├── data/ # 原始数据和导出数据 └── db.sqlite3 # SQLite 数据库文件

4. 系统架构与数据库设计

4.1 整体架构

整个项目可以拆分成四个核心模块:

  1. 数据采集模块:爬取商品列表、商品详情、价格、销量、评论等公开数据。
  2. 数据预处理模块:用 pandas 做空值处理、去重、格式统一,再把数据写入数据库。
  3. 数据分析与可视化模块:统计销量分布、价格区间、评论关键词,生成图表和词云图。
  4. 销量预测模块:基于历史数据训练机器学习模型,输入商品特征输出预测销量。

Django 在这里的作用是“粘合层”。它既负责接收爬虫采集的数据,也负责把分析结果渲染到 Web 页面,同时提供接口给前端调用。

4.2 数据库模型设计

以商品和销量数据为例,定义 Django Model。

# apps/goods/models.py from django.db import models class Product(models.Model): product_id = models.CharField(max_length=64, unique=True, verbose_name="商品ID") title = models.CharField(max_length=255, verbose_name="商品标题") category = models.CharField(max_length=64, verbose_name="商品类目") price = models.FloatField(verbose_name="价格") sales = models.IntegerField(default=0, verbose_name="销量") shop_name = models.CharField(max_length=128, verbose_name="店铺名称") created_at = models.DateTimeField(auto_now_add=True, verbose_name="采集时间") class Meta: db_table = "product" verbose_name = "商品信息" class SalesRecord(models.Model): product = models.ForeignKey(Product, on_delete=models.CASCADE, verbose_name="关联商品") record_date = models.DateField(verbose_name="记录日期") sales_volume = models.IntegerField(verbose_name="当日销量") price = models.FloatField(verbose_name="当日价格") class Meta: db_table = "sales_record" verbose_name = "销量记录"

执行数据库迁移:

python manage.py makemigrations python manage.py migrate

5. 数据采集模块:爬虫功能与实现

爬虫部分是这个项目的数据入口。如果爬虫拿不到数据,后面的分析和预测都是空谈。但爬虫也是整个项目里最需要“克制”的部分。

建议只抓取公开的商品页面信息,并在代码里设置请求间隔。简单实现可以用 requests + BeautifulSoup,复杂场景再用 Scrapy。

5.1 使用 requests + BeautifulSoup 采集商品列表

# apps/crawler/services.py import time import random import requests from bs4 import BeautifulSoup def fetch_product_list(keyword, pages=1): """ 抓取公开商品列表信息。 注意:仅用于学习研究,需遵守目标网站 robots 协议。 """ headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) " "AppleWebKit/537.36 (KHTML, like Gecko) " "Chrome/120.0.0.0 Safari/537.36" } results = [] for page in range(1, pages + 1): url = f"https://example.com/search?keyword={keyword}&page={page}" try: resp = requests.get(url, headers=headers, timeout=10) resp.raise_for_status() soup = BeautifulSoup(resp.text, "html.parser") # 解析逻辑需要按目标页面结构调整 # item_list = soup.select(".item") # for item in item_list: # ... except requests.RequestException as e: print(f"第 {page} 页抓取失败: {e}") # 控制请求频率 time.sleep(random.uniform(1, 3)) return results

这里没有写死具体解析逻辑,因为不同平台的页面结构差异很大。你自己使用时需要打开目标页面,用浏览器开发者工具找到商品列表的 CSS 选择器。

5.2 采集后的数据入库

把爬到的数据清洗后写入数据库。

# apps/crawler/tasks.py import pandas as pd from apps.goods.models import Product def save_products_from_dataframe(df): """ df 需要包含字段: product_id, title, category, price, sales, shop_name """ df = df.drop_duplicates(subset=["product_id"]) df = df.dropna(subset=["product_id", "title"]) df["price"] = pd.to_numeric(df["price"], errors="coerce").fillna(0) for _, row in df.iterrows(): Product.objects.update_or_create( product_id=row["product_id"], defaults={ "title": row["title"], "category": row["category"], "price": row["price"], "sales": int(row["sales"]), "shop_name": row["shop_name"], } )

6. 数据清洗与数据预处理

真实爬下来的数据基本不可能直接用来训练模型。常见问题包括:价格字段带货币符号、销量数据是字符串、有重复记录、时间字段格式不统一。

6.1 用 pandas 做清洗

# apps/analysis/data_clean.py import pandas as pd def clean_sales_data(df): # 去重 df = df.drop_duplicates() # 删除关键字段为空的行 df = df.dropna(subset=["product_id", "record_date"]) # 价格转数字,去掉非数字字符 df["price"] = ( df["price"] .astype(str) .str.replace("¥", "") .str.replace(",", "") .astype(float) ) # 销量转数字 df["sales_volume"] = pd.to_numeric(df["sales_volume"], errors="coerce").fillna(0) # 日期统一格式 df["record_date"] = pd.to_datetime(df["record_date"], errors="coerce") # 过滤异常值 df = df[df["price"] > 0] df = df[df["sales_volume"] >= 0] return df

清洗逻辑要写进 Django management command,方便命令行手动执行。

python manage.py clean_data

7. 数据分析与可视化功能

数据显示是 Web 系统最容易出效果的部分。Django 后端把 DataFrame 统计结果转成 JSON,前端用 ECharts 渲染,这是目前比较常见的组合。

7.1 销量 Top10 商品统计

# apps/analysis/views.py import json import pandas as pd from django.shortcuts import render from apps.goods.models import Product def sales_rank(request): # 从数据库读取商品数据 queryset = Product.objects.all().values("title", "sales") df = pd.DataFrame(list(queryset)) if df.empty: chart_data = [] else: top10 = df.sort_values("sales", ascending=False).head(10) chart_data = { "titles": top10["title"].tolist(), "sales": top10["sales"].astype(int).tolist() } return render(request, "analysis.html", { "chart_data": json.dumps(chart_data, ensure_ascii=False) })

前端模板里用 ECharts 渲染:

<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <title>销量分析</title> <script src="https://cdn.jsdelivr.net/npm/echarts@5/dist/echarts.min.js"></script> </head> <body> <div id="chart" style="width: 800px; height: 500px;"></div> <script> const rawData = JSON.parse('{{ chart_data|escapejs }}'); const chart = echarts.init(document.getElementById('chart')); chart.setOption({ title: { text: '销量 Top10 商品' }, tooltip: {}, xAxis: { data: rawData.titles }, yAxis: {}, series: [{ type: 'bar', data: rawData.sales }] }); </script> </body> </html>

7.2 价格区间分布

用 pandas 的cut函数对价格分箱。

import pandas as pd def price_distribution(df): bins = [0, 50, 100, 200, 500, 1000, 5000] labels = ["0-50", "50-100", "100-200", "200-500", "500-1000", "1000+"] df["price_range"] = pd.cut(df["price"], bins=bins, labels=labels, right=False) result = df["price_range"].value_counts().reindex(labels).fillna(0) return result.to_dict()

8. 词云图功能实现

词云图是电商评论分析里最直观的展示方式。通过分析用户评论的高频词,可以看出商品口碑集中在哪些方面,比如“质量”“物流”“尺寸”“颜值”等。

8.1 中文分词与词云生成

中文文本需要先用 jieba 分词,然后用 wordcloud 生成图片。

# apps/analysis/wordcloud_utils.py import jieba from wordcloud import WordCloud def generate_comment_wordcloud(comments: list, output_path: str): """ comments: 评论文本列表 output_path: 输出图片路径 """ # 停用词,按需补充 stopwords = {"这个", "一个", "没有", "什么", "自己", "就是", "真的"} # 分词并过滤停用词 word_list = [] for comment in comments: words = jieba.lcut(comment) for w in words: w = w.strip() if w and w not in stopwords and len(w) > 1: word_list.append(w) text = " ".join(word_list) # Windows 下需要指定中文字体路径 wc = WordCloud( font_path="C:/Windows/Fonts/simhei.ttf", width=800, height=600, background_color="white", max_words=200 ) wc.generate(text) wc.to_file(output_path)

注意,font_path在 Linux 环境下要改成系统中文字体路径,例如/usr/share/fonts/truetype/wqy/wqy-zenhei.ttc。如果没有中文字体,词云图会出现方块乱码。

8.2 在 Django 视图中调用

def wordcloud_view(request): comments = [...] # 从数据库读取评论 output_path = os.path.join(settings.BASE_DIR, "static/images/wordcloud.png") generate_comment_wordcloud(comments, output_path) return render(request, "wordcloud.html", {"image_url": "/static/images/wordcloud.png"})

小型数据集直接实时生成没问题。如果评论量很大,建议用定时任务提前生成,页面里只展示图片,避免每次请求都重新跑一遍分词。

9. 机器学习销量预测算法

销量预测是项目里最有技术含量的模块。算法思路很简单:用历史数据训练模型,输入商品的特征(价格、类目、历史销量、节假日等),输出预测的销量值。

9.1 特征构造

模型的精度很大程度上取决于特征。可以从原始数据中构造以下特征:

  • 商品价格
  • 商品所属类目(需要编码)
  • 前一天销量
  • 前七天平均销量
  • 前三十天平均销量
  • 距离最近促销日的天数
  • 星期几
def build_features(df): df = df.sort_values(["product_id", "record_date"]) df["sales_lag1"] = df.groupby("product_id")["sales_volume"].shift(1) df["sales_lag7_mean"] = df.groupby("product_id")["sales_volume"].transform( lambda x: x.rolling(7, min_periods=1).mean() ) df["weekday"] = df["record_date"].dt.weekday df = df.dropna(subset=["sales_lag1"]) return df

9.2 使用随机森林回归训练模型

# apps/prediction/models_train.py import pandas as pd from sklearn.ensemble import RandomForestRegressor from sklearn.model_selection import train_test_split from sklearn.metrics import mean_absolute_error import joblib def train_sales_model(df): features = ["price", "sales_lag1", "sales_lag7_mean", "weekday"] X = df[features] y = df["sales_volume"] X_train, X_test, y_train, y_test = train_test_split( X, y, test_size=0.2, random_state=42 ) model = RandomForestRegressor( n_estimators=200, max_depth=10, random_state=42 ) model.fit(X_train, y_train) y_pred = model.predict(X_test) mae = mean_absolute_error(y_test, y_pred) print(f"MAE: {mae:.2f}") # 保存模型 joblib.dump(model, "sales_model.pkl") return model

9.3 Django 中加载模型并预测

训练完成后,模型保存为.pkl文件。Django 启动时加载模型,预测接口直接使用,避免每次请求都重新加载。

# apps/prediction/services.py import joblib import pandas as pd _model = None def get_model(): global _model if _model is None: _model = joblib.load("sales_model.pkl") return _model def predict_sales(price, lag1, lag7_mean, weekday): model = get_model() input_df = pd.DataFrame([{ "price": price, "sales_lag1": lag1, "sales_lag7_mean": lag7_mean, "weekday": weekday }]) return model.predict(input_df)[0]

10. Django Web 系统整合

把前面几个模块整合进 Django,需要定义好 URL 路由和视图。

10.1 URL 配置

# urls.py from django.urls import path from apps.analysis import views as analysis_views from apps.prediction import views as prediction_views urlpatterns = [ path("admin/", admin.site.urls), path("", analysis_views.index, name="index"), path("analysis/", analysis_views.sales_rank, name="sales_rank"), path("wordcloud/", analysis_views.wordcloud_view, name="wordcloud"), path("predict/", prediction_views.predict_view, name="predict"), ]

10.2 预测页面视图

# apps/prediction/views.py from django.shortcuts import render from django.http import JsonResponse from apps.prediction.services import predict_sales def predict_view(request): if request.method == "POST": price = float(request.POST.get("price", 0)) lag1 = float(request.POST.get("sales_lag1", 0)) lag7_mean = float(request.POST.get("sales_lag7_mean", 0)) weekday = int(request.POST.get("weekday", 0)) result = predict_sales(price, lag1, lag7_mean, weekday) return JsonResponse({"predict_sales": round(result, 2)}) return render(request, "prediction.html")

这样系统就完成了从数据采集到 Web 预测的闭环。

11. 接口 API 与批量任务

如果想把预测能力开放给其他系统,可以直接写 JSON 接口。

11.1 简单接口示例

# apps/prediction/api.py import json from django.http import JsonResponse from django.views.decorators.csrf import csrf_exempt from apps.prediction.services import predict_sales @csrf_exempt def predict_api(request): if request.method != "POST": return JsonResponse({"error": "only POST allowed"}, status=405) try: data = json.loads(request.body) price = float(data.get("price", 0)) lag1 = float(data.get("sales_lag1", 0)) lag7_mean = float(data.get("sales_lag7_mean", 0)) weekday = int(data.get("weekday", 0)) result = predict_sales(price, lag1, lag7_mean, weekday) return JsonResponse({"code": 0, "data": {"predict_sales": round(result, 2)}}) except Exception as e: return JsonResponse({"code": 1, "msg": str(e)}, status=400)

调用示例:

curl -X POST http://127.0.0.1:8000/api/predict \ -H "Content-Type: application/json" \ -d '{"price": 99.9, "sales_lag1": 120, "sales_lag7_mean": 105, "weekday": 3}'

返回:

{ "code": 0, "data": { "predict_sales": 118.37 } }

11.2 批量预测

批量场景下,可以把待预测数据放到一个 CSV 文件里,逐行调用模型,最后导出结果。

import pandas as pd import joblib def batch_predict(input_csv, output_csv): df = pd.read_csv(input_csv) model = joblib.load("sales_model.pkl") features = ["price", "sales_lag1", "sales_lag7_mean", "weekday"] df["predict_sales"] = model.predict(df[features]) df.to_csv(output_csv, index=False, encoding="utf-8-sig")

批量前建议做数据校验,比如字段名是否完整、缺失值是否处理、数值字段能否转成 float。一次批量任务最好记录日志,方便排查是哪一行数据导致的异常。

12. 资源占用与性能观察

12.1 运行资源

这个项目的所有模块都基于 CPU 运行,对硬件没有特别要求。8GB 内存的机器跑 Django + 爬虫 + 数据分析完全没问题。如果同时处理几十万条数据,内存会明显上涨,建议把数据量控制在十万行以内,或者改用数据库聚合查询,而不是一次性全量加载到 DataFrame。

12.2 观察指标

在任务执行过程中可以关注:

  • 内存占用:Windows 任务管理器、Linux 的free -h
  • CPU 使用率:训练随机森林时 CPU 会占满,属正常现象。
  • 接口耗时:在 Django 日志里输出每个请求的处理时间,对比不同数据量下的延迟。
  • 数据库体积:SQLite 文件大小会随爬虫数据量增长,定期清理无效数据。

12.3 性能优化建议

  • 爬虫使用 Scrapy 的异步能力,比 requests 循环快很多。
  • 数据分析尽量用 pandas 的向量化操作,避免 for 循环。
  • 模型训练用joblib.dump保存,不用每次启动都重新训练。
  • 图表数据在 Django 视图里提前算好,前端只负责渲染,减少浏览器端计算压力。
  • 词云图生成比较耗时,改成定时生成并缓存图片。

13. 常见问题与排查方法

问题现象可能原因排查方式解决方案
pip install安装依赖失败Python 版本不符或网络问题查看 pip 错误日志切换 Python 3.8 ~ 3.11,使用国内镜像源
执行python manage.py提示命令找不到虚拟环境未激活或环境变量错误执行which python激活虚拟环境后重试
爬虫请求被拒绝User-Agent 被识别或请求频率过高打印响应状态码和 body设置合理请求头,降低频率,使用代理池时要确保合法合规
数据入库报错DataFrame 列名与 Model 字段不匹配打印 DataFrame 列名统一字段命名,或者在入库前做 rename
词云图出现乱码方块中文字体路径错误检查字体文件是否存在指定系统中文字体路径
预测接口返回 400请求字段缺失或类型不对查看 Django 终端异常增加参数校验,返回具体错误信息
随机森林训练报错包含 NaN特征列有空值df.isnull().sum()检查使用 fillna 填充或丢到缺失行
批量预测卡住数据量过大或死循环打印当前处理行号分批处理,每次 1000 行
端口被占用其他服务占用 8000`netstat -anofindstr 8000`

14. 最佳实践与使用建议

如果你打算把这个项目跑通并延伸到自己的场景,下面几条建议值得收藏。

第一,先跑通最小闭环。不要一上来就想做完整的电商平台数据采集,先用自己的测试数据生成一套“数据表 → 分析 → 可视化 → 预测”的最小系统。页面丑没关系,重点是链路通。

第二,爬虫与数据入库分离。爬虫脚本单独运行,数据落到 CSV 或数据库后,再执行清洗和入库。不要把采集逻辑写进 Django 请求视图里,否则页面响应会非常慢。

第三,做好数据备份。爬虫数据、清洗后的数据、训练好的模型文件、词云图图片,建议分目录管理。模型重新训练前,把旧版本重命名备份,不要直接覆盖。

第四,模型训练和预测分离。训练脚本独立于 Web 系统运行,预测接口只负责加载现有模型。这样可以避免每次请求都触发训练任务。

第五,接口服务限制访问范围。如果开放了预测 API,建议在 Django 里做简单的访问控制,例如只允许本机访问,或增加一个 token 校验。

第六,涉及评论、销量、价格等数据时,注意来源的授权和合规模糊性。研究学习可以,上线商用前必须确认数据来源是否符合平台规则,是否涉及个人信息保护要求。

第七,模型评估指标要记录。训练时保存 MAE、RMSE 到文件或数据库,方便对比不同算法的效果。

15. 总结与下一步

这套基于 Django 的电商数据分析系统,值得优先验证的是整条链路能否跑通:爬虫拿回数据,pandas 完成清洗,Django 渲染可视化页面,最后用机器学习模型给出销量预测结果。技术栈覆盖全面,但每个模块都有明确的边界,非常适合做课程设计或毕设的底子。

最容易踩的坑有三个:一是爬虫解析时依赖网页结构,目标网站改版就会失效;二是词云图中文字体配置缺失导致乱码;三是特征构造不完整导致预测结果偏差大。前两个是环境问题,第三个是算法问题,调试时按“环境 → 数据 → 模型”的顺序排查会更快。

下一步可以扩展的方向不少:把销量预测换成 ARIMA 或 LSTM 等时序模型;把 Django 原生渲染替换成 Vue + DRF 前后端分离;增加数据看板页,用多个图表展示销售趋势;把爬虫改成定时任务,每天自动更新数据。

这个项目最实际的收获是,你能在一套系统里看到数据从网络到数据库、再到图表和模型预测的完整流动过程。这个过程跑通之后,后面做任何数据分析类项目,都会顺手很多。建议收藏备用,也欢迎部署测试后回来交流你的改造思路。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询