Python电商销量预测系统:从爬虫到随机森林可视化大屏

发布时间:2026/8/31 3:19:32
Python电商销量预测系统:从爬虫到随机森林可视化大屏 做电商数据分析方向的同学应该都有过类似的困惑数据能从哪儿来、抓下来的数据怎么清洗、销量预测到底用哪种模型才靠谱、预测结果又如何展示给业务方看。尤其是母婴用品这类消费频次高、季节波动明显的类目单纯靠Excel透视表已经很难支撑精细化运营。这篇文章就围绕一套完整的“Python电商销量分析与预测系统”展开把爬虫采集、Django后端、随机森林回归预测、可视化大屏以及购物管理系统串联起来从零到一拆解实现思路和关键代码。无论你是正在做毕业设计还是希望在公司内部搭建一套可用的电商数据看板这篇文章都能给你一个比较完整的技术参考。1. 系统到底要解决什么问题1.1 业务场景与核心痛点母婴用品行业有一个明显特点品类多、SKU更新快、季节性明显。比如婴儿纸尿裤在“618”和“双11”前后销量会明显抬升新生儿礼盒在春节前会有一波小高峰。如果只靠人工经验备货要么库存积压要么热卖款断货。从数据分析的角度看需要解决三件事数据从哪来没有销售数据的冷启动阶段需要通过爬虫采集公开的电商平台数据例如商品标题、价格、月销量、评论数、店铺信息等。数据怎么用采集完的数据往往存在缺失值、重复值、异常值需要做清洗和特征工程才能进入机器学习模型。预测结果怎么落地训练好的销量预测模型不能只停留在Jupyter Notebook里应该集成到Web系统中让运营人员可以按商品、按时间查看预测值并基于预测结果辅助备货决策。1.2 系统功能拆解本文实现的系统包含四个核心模块模块负责内容关键技术数据采集模块爬取淘宝/天猫等平台的母婴商品公开数据Python、requests、BeautifulSoup、selenium数据存储模块商品、订单、用户、预测结果入库MySQL、Django ORM销量预测模块基于历史销量数据训练随机森林回归模型scikit-learn、pandas、joblib可视化与Web管理展示销量趋势、商品排行、预测结果管理商品和订单Django、ECharts、Bootstrap整个架构采用经典的B/S模式后端由Django提供API和页面渲染前端通过ECharts完成可视化大屏展示预测模型以独立服务的形式封装在Django视图函数中。1.3 适用读者与前置知识如果你是Python入门不久的开发者希望拿一个完整的项目来练手那么这个系统可以帮助你把爬虫、Web开发、机器学习、可视化这几个知识点串联起来。如果你是计算机相关专业的学生正在准备毕业设计或课程设计这套系统的模块划分和文档结构同样可以直接参考。前置要求熟悉Python基础语法了解pandas和scikit-learn的基本用法对Django框架有一定认知。如果Django不熟也不影响文中会给出完整配置和代码。2. 技术选型与环境准备2.1 技术栈说明这是一个教学型完整项目技术选型没有追求过于复杂而是强调稳定和易上手开发语言Python 3.8推荐3.9或3.10避免过高版本导致部分依赖包不支持Web框架Django 3.2或4.x版本不同有一些细节差异本文以4.x为例但兼容3.2的写法机器学习库scikit-learn 1.0以上数据清洗与处理pandas、numpy数据库MySQL 5.7也可以直接使用Django默认的SQLite作为演示前端可视化ECharts 5.x通过CDN或本地静态文件引入爬虫requests、BeautifulSoup4、selenium按需需要强调的是不同版本之间确实存在兼容性问题。比如在Python 3.11环境下安装旧版scikit-learn可能会失败建议读者创建独立的虚拟环境进行安装。2.2 创建虚拟环境在正式开始编码之前建议先为项目创建独立的虚拟环境。# 创建虚拟环境 python -m venv sales_env # 激活虚拟环境Windows sales_env\Scripts\activate # 激活虚拟环境Mac/Linux source sales_env/bin/activate激活后命令行前面会出现(sales_env)前缀说明当前已经进入虚拟环境。2.3 安装依赖包整个项目需要的核心依赖如下pip install django4.2.7 pip install pandas2.0.3 pip install numpy1.24.3 pip install scikit-learn1.3.2 pip install requests2.31.0 pip install beautifulsoup44.12.2 pip install pymysql1.1.0 pip install joblib1.3.2这里固定了版本号是为了保证教程中代码的稳定性。如果你的网络环境访问PyPI较慢可以切换为清华镜像源pip install -i https://pypi.tuna.tsinghua.edu.cn/simple django4.2.7安装完成后可以通过以下命令验证python -c import django; print(django.get_version()) python -c import sklearn; print(sklearn.__version__)如果命令行能正常输出版本号说明环境配置成功。2.4 数据库准备本文使用MySQL作为业务数据存储但考虑到部分读者本机没有安装MySQLDjango项目的数据库配置可以灵活切换。如果为了省事可以直接使用SQLite代码层面不需要任何改动因为Django ORM统一了数据库操作。如果使用MySQL需要提前创建数据库CREATE DATABASE IF NOT EXISTS baby_sales DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;安装pymysql后还需要在Django项目的__init__.py中写入import pymysql pymysql.install_as_MySQLdb()这样Django才能通过MySQLdb协议连接到MySQL。3. 数据采集爬虫设计与合规清洗3.1 爬虫思路与合规边界很多同学第一次写爬虫最担心的就是“抓取淘宝会不会有问题”。这里需要明确一个边界爬虫技术本身是中性工具但使用方式必须合法合规。只采集公开可见的数据不突破登录权限不绕过反爬校验。遵守目标网站的robots协议。控制请求频率避免对目标服务器造成压力。本文采集的数据仅用于学习、研究和学术演示不用于商业用途。演示时建议使用模拟数据或公开的免费接口不要大规模爬取真实生产环境。因此本文将爬虫设计为两个阶段第一阶段演示如何爬取一个类似淘宝的公开页面或mock接口第二阶段将原始数据清洗为标准格式。实际课程设计或者公司内部项目中更推荐直接使用内部订单数据或已授权的第三方数据。3.2 爬虫代码示例以爬取商品搜索页为例目标字段包括商品标题、价格、月销量、店铺名称、商品链接。# 文件路径spider/taobao_spider.py import requests import pandas as pd from bs4 import BeautifulSoup import time import random HEADERS { User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36 } def fetch_goods_list(keyword, pages3): 模拟爬取商品列表页返回商品信息列表。 注意这里使用演示URL实际采集时必须遵守目标网站规则。 goods_list [] for page in range(1, pages 1): # 演示接口实际使用时请替换为合规目标 url fhttps://example.com/search?q{keyword}page{page} try: resp requests.get(url, headersHEADERS, timeout10) resp.raise_for_status() resp.encoding utf-8 except requests.RequestException as e: print(f[WARN] 第{page}页请求失败: {e}) continue soup BeautifulSoup(resp.text, html.parser) # 解析商品列表 items soup.select(.goods-item) # 选择器需要根据实际页面调整 for item in items: title item.select_one(.title).text.strip() price_text item.select_one(.price).text.strip() sales_text item.select_one(.sales).text.strip() shop_name item.select_one(.shop).text.strip() link item.select_one(a).get(href) price float(price_text.replace(¥, )) sales int(sales_text.replace(月销, ).replace(, )) goods_list.append({ title: title, price: price, month_sales: sales, shop_name: shop_name, link: link, }) time.sleep(random.uniform(1, 3)) # 控制请求频率 return goods_list if __name__ __main__: data fetch_goods_list(婴儿纸尿裤, pages2) df pd.DataFrame(data) df.to_csv(data/baby_diaper.csv, indexFalse, encodingutf-8-sig) print(df.head())3.3 爬取数据后的清洗流程真实爬取的数据不可能直接使用清洗是整个项目中非常关键的一步。常见的清洗操作包括去除重复商品根据商品链接或商品标题去重。价格异常处理单位不一致、免费赠品、价格缺失。月销量缺失填充如果部分商品没有销量数据可以根据同类目平均值填充。标题清洗去掉表情符号、多余空格、营销词如【爆款】等。下面给出一个清洗示例# 文件路径spider/data_clean.py import pandas as pd import re def clean_goods_data(df): # 1. 删除完全重复的行 df df.drop_duplicates(subset[link]) # 2. 价格字段清洗保证为数值类型 df[price] pd.to_numeric(df[price], errorscoerce) # 3. 月销量缺失值处理用中位数填充 df[month_sales] df[month_sales].fillna(df[month_sales].median()) # 4. 标题清洗去掉多余符号 def clean_title(text): if pd.isna(text): return text re.sub(r【.*?】, , str(text)) text re.sub(r\s, , text).strip() return text df[title] df[title].apply(clean_title) # 5. 增加销量等级和价格区间等衍生字段 df[price_level] pd.cut(df[price], bins[0, 50, 100, 200, 500, 99999], labels[0-50, 50-100, 100-200, 200-500, 500]) df[sales_level] pd.cut(df[month_sales], bins[0, 100, 500, 1000, 5000, 100000], labels[S0, S1, S2, S3, S4]) return df3.4 为什么选择CSV作为中间存储很多情况下爬虫采集的数据不必立即入库。CSV文件在开发和调试阶段非常灵活可以直接用pandas读取也可以导入数据库。本文项目在数据采集模块后设置了一个data/目录专门存放原始CSV和清洗后的CSV。这种做法的好处是爬虫程序、数据处理程序、Django后端服务可以拆开运行互不影响。当后期需要更换数据源时只需要重新生成CSV即可模型训练部分几乎不需要修改。4. Django后端与数据库设计4.1 创建Django项目和应用激活虚拟环境后进入项目根目录执行以下命令django-admin startproject sales_system cd sales_system python manage.py startapp goods python manage.py startapp orders python manage.py startapp predict项目结构最终建议如下sales_system/ ├── manage.py ├── sales_system/ │ ├── __init__.py │ ├── settings.py │ ├── urls.py │ └── wsgi.py ├── goods/ │ ├── models.py │ ├── views.py │ ├── urls.py │ └── admin.py ├── orders/ │ ├── models.py │ ├── views.py │ └── urls.py ├── predict/ │ ├── models.py │ ├── views.py │ └── urls.py ├── static/ │ ├── css/ │ └── js/ ├── templates/ │ ├── goods/ │ ├── orders/ │ └── predict/ └── data/ ├── baby_diaper.csv └── clean_baby_diaper.csv4.2 settings.py 关键配置在INSTALLED_APPS中注册新增的应用并在DATABASES中配置MySQL或SQLite。# 文件路径sales_system/settings.py INSTALLED_APPS [ django.contrib.admin, django.contrib.auth, django.contrib.contenttypes, django.contrib.sessions, django.contrib.messages, django.contrib.staticfiles, goods, orders, predict, ] # 如果使用SQLite DATABASES { default: { ENGINE: django.db.backends.sqlite3, NAME: BASE_DIR / db.sqlite3, } } # 如果使用MySQL请改为以下配置 # DATABASES { # default: { # ENGINE: django.db.backends.mysql, # NAME: baby_sales, # USER: root, # PASSWORD: your_password, # HOST: 127.0.0.1, # PORT: 3306, # OPTIONS: { # charset: utf8mb4, # }, # } # }设置模板查找路径TEMPLATES [ { BACKEND: django.template.backends.django.DjangoTemplates, DIRS: [BASE_DIR / templates], APP_DIRS: True, OPTIONS: { context_processors: [ django.template.context_processors.debug, django.template.context_processors.request, django.contrib.auth.context_processors.auth, django.contrib.messages.context_processors.messages, ], }, }, ]4.3 商品与订单模型设计针对母婴用品购物管理系统我们设计两个核心数据模型。商品模型字段包括商品标题、一级类目、价格、库存、月销量、累计评价数、上下架状态和创建时间。# 文件路径goods/models.py from django.db import models class Category(models.Model): 商品类目 name models.CharField(类目名称, max_length50) parent models.ForeignKey(self, nullTrue, blankTrue, on_deletemodels.SET_NULL, verbose_name父级类目) class Meta: verbose_name 商品类目 verbose_name_plural verbose_name def __str__(self): return self.name class Product(models.Model): 商品信息 title models.CharField(商品标题, max_length255) category models.ForeignKey(Category, on_deletemodels.SET_NULL, nullTrue, blankTrue, verbose_name类目) price models.DecimalField(售价, max_digits10, decimal_places2) stock models.IntegerField(库存, default0) month_sales models.IntegerField(月销量, default0) comment_count models.IntegerField(累计评价数, default0) is_active models.BooleanField(是否上架, defaultTrue) created_at models.DateTimeField(创建时间, auto_now_addTrue) class Meta: verbose_name 商品 verbose_name_plural verbose_name ordering [-month_sales] def __str__(self): return self.title订单模型主要负责购物管理系统的核心交易数据积累。实际做销量预测时最理想的数据源就是订单表因为它包含了真实的成交时间、数量和金额。# 文件路径orders/models.py from django.db import models from django.contrib.auth.models import User from goods.models import Product class Order(models.Model): 订单主表 ORDER_STATUS ( (pending, 待付款), (paid, 已付款), (shipped, 已发货), (completed, 已完成), (cancelled, 已取消), ) order_no models.CharField(订单编号, max_length64, uniqueTrue) user models.ForeignKey(User, on_deletemodels.CASCADE, verbose_name用户) total_amount models.DecimalField(订单金额, max_digits10, decimal_places2) status models.CharField(订单状态, max_length16, choicesORDER_STATUS, defaultpending) created_at models.DateTimeField(下单时间, auto_now_addTrue) class Meta: verbose_name 订单 verbose_name_plural verbose_name def __str__(self): return self.order_no class OrderItem(models.Model): 订单明细 order models.ForeignKey(Order, related_nameitems, on_deletemodels.CASCADE, verbose_name订单) product models.ForeignKey(Product, on_deletemodels.CASCADE, verbose_name商品) quantity models.IntegerField(购买数量, default1) price models.DecimalField(成交单价, max_digits10, decimal_places2) class Meta: verbose_name 订单明细 verbose_name_plural verbose_name def __str__(self): return f{self.order.order_no}-{self.product.title}完成模型编写后依次执行数据库迁移命令python manage.py makemigrations python manage.py migrate这里有一个新手容易踩的坑如果修改了models.py中的字段但忘记执行makemigrations启动服务后Django会报django.db.utils.OperationalError: no such table或者字段不存在的错误。所以每次调整模型后都要重新执行迁移。4.4 购物管理基础功能以商品列表为例最简单的方式是使用Django的ListView或自定义视图函数。这里为了演示方便使用函数视图# 文件路径goods/views.py from django.shortcuts import render from django.core.paginator import Paginator from .models import Product def product_list(request): 商品列表页支持按关键字搜索和按价格排序 keyword request.GET.get(keyword, ) sort request.GET.get(sort, ) products Product.objects.filter(is_activeTrue) if keyword: products products.filter(title__icontainskeyword) if sort price_asc: products products.order_by(price) elif sort price_desc: products products.order_by(-price) else: products products.order_by(-month_sales) paginator Paginator(products, 12) page request.GET.get(page) page_obj paginator.get_page(page) context { page_obj: page_obj, keyword: keyword, sort: sort, } return render(request, goods/product_list.html, context)对应的URL路由配置# 文件路径goods/urls.py from django.urls import path from . import views urlpatterns [ path(products/, views.product_list, nameproduct_list), ] # 文件路径sales_system/urls.py from django.contrib import admin from django.urls import path, include urlpatterns [ path(admin/, admin.site.urls), path(, include(goods.urls)), path(, include(orders.urls)), path(, include(predict.urls)), ]模板文件这里不做大篇幅展开核心思路是使用一个表格或卡片列表展示商品信息关键字段包括商品标题、价格、月销量、库存、类目。建议引入Bootstrap做基础样式提升页面观感。5. 随机森林回归销量预测模型构建5.1 为什么选择随机森林回归销量预测本质上是一个回归问题。业界常用的方案包括线性回归、决策树、随机森林、XGBoost、LSTM等。不同方法各有优劣线性回归解释性强但对非线性关系拟合能力弱。决策树可以捕捉非线性关系但容易过拟合。随机森林通过多棵决策树集成能有效降低过拟合对异常值不敏感适合表格型数据。XGBoost/LightGBM精度通常更高但调参复杂度也更高。对于母婴用品销量预测这个场景历史数据量不大特征以商品属性、价格、历史销量为主随机森林回归不仅可以提供不错的预测精度还能输出特征重要性帮助我们分析哪些因素对销量影响最大。这也是课程设计和中小型项目中推荐使用随机森林的原因。5.2 特征工程以订单表或商品表为基础我们可以构造以下特征商品价格。商品所属类目。商品历史月销量。商品累计评价数。距上架时间的月份数。季节特征如是否是促销月份。价格区间编码。类目编码。特征工程的核心目的是让模型从数据中发现规律。例如价格和销量之间可能存在反比关系评价数量和销量存在正相关关系。下面给出特征工程的代码示例# 文件路径predict/feature_engineering.py import pandas as pd import numpy as np def build_features(df): 输入df需要包含字段 price, month_sales, comment_count, category, level, created_at data df.copy() # 时间特征上架月份 data[created_at] pd.to_datetime(data[created_at]) data[listing_month] data[created_at].dt.month # 季节特征 data[is_promotion] data[listing_month].isin([6, 11]).astype(int) # 类目编码 data[category_code] data[category].astype(category).cat.codes # 价格分箱后编码 data[price_level_code] data[price_level].astype(category).cat.codes # 特征列 features [ price, comment_count, listing_month, category_code, price_level_code, is_promotion ] X data[features] y data[month_sales] return X, y5.3 随机森林回归模型训练训练过程分为四步读取CSV数据。特征工程。划分训练集和测试集。训练随机森林回归模型并评估。完整代码如下# 文件路径predict/train_model.py import pandas as pd import joblib from sklearn.model_selection import train_test_split from sklearn.ensemble import RandomForestRegressor from sklearn.metrics import mean_squared_error, r2_score, mean_absolute_error from feature_engineering import build_features # 1. 读取清洗后的数据 df pd.read_csv(../data/clean_baby_diaper.csv) # 2. 特征工程 X, y build_features(df) # 3. 划分训练集和测试集设置随机种子保证可复现 X_train, X_test, y_train, y_test train_test_split( X, y, test_size0.2, random_state42 ) # 4. 训练随机森林回归模型 model RandomForestRegressor( n_estimators200, max_depth10, min_samples_split5, min_samples_leaf2, random_state42, n_jobs-1 ) model.fit(X_train, y_train) # 5. 模型评估 y_pred model.predict(X_test) mse mean_squared_error(y_test, y_pred) mae mean_absolute_error(y_test, y_pred) r2 r2_score(y_test, y_pred) print(f均方误差 MSE: {mse:.2f}) print(f平均绝对误差 MAE: {mae:.2f}) print(f决定系数 R2: {r2:.4f}) # 6. 特征重要性 feature_importance pd.DataFrame({ feature: X.columns, importance: model.feature_importances_ }).sort_values(importance, ascendingFalse) print(特征重要性) print(feature_importance) # 7. 保存模型供Django调用 joblib.dump(model, ../models/sales_rf_model.pkl)5.4 参数解释随机森林中有几个关键参数值得关注n_estimators决策树的数量。树越多模型越稳定但训练时间越长。一般建议100到500之间。max_depth每棵树的最大深度。限制深度可以防止过拟合。min_samples_split内部节点再划分所需的最小样本数。值越大树越保守。min_samples_leaf叶节点所需的最小样本数。同样起到正则化作用。random_state随机种子固定后每次运行结果一致方便复现。n_jobs-1使用所有CPU核心并行训练。5.5 模型评估结果解读如果训练完成后R2在0.8以上说明模型能解释80%以上的销量波动这对预测任务来说已经是不错的表现。MAE表示平均预测误差比如预测月销量为1000件实际为1050件那么误差在50件左右。业务上通常更关心MAE因为它直接反映预测偏差的大小。如果模型效果不理想优先检查特征工程是否合理其次再调参。不要一上来就盲目调参。6. 可视化模块与预测页面集成6.1 Django视图加载模型训练好的模型保存在models/sales_rf_model.pkl文件中接下来在Django中加载并完成预测。# 文件路径predict/views.py import joblib import pandas as pd from django.shortcuts import render from django.http import JsonResponse # 加载模型注意这里的路径根据项目实际结构调整 MODEL_PATH models/sales_rf_model.pkl model joblib.load(MODEL_PATH) def predict_sales(request): 销量预测接口支持GET参数传入商品属性 if request.method GET: price float(request.GET.get(price, 99)) comment_count int(request.GET.get(comment_count, 100)) listing_month int(request.GET.get(listing_month, 10)) category_code int(request.GET.get(category_code, 0)) price_level_code int(request.GET.get(price_level_code, 2)) is_promotion int(request.GET.get(is_promotion, 0)) # 构造特征数组注意顺序必须与训练时一致 features pd.DataFrame([[ price, comment_count, listing_month, category_code, price_level_code, is_promotion ]], columns[ price, comment_count, listing_month, category_code, price_level_code, is_promotion ]) pred_sales model.predict(features)[0] return JsonResponse({ code: 0, message: success, data: { pred_sales: round(float(pred_sales), 2) } }) return JsonResponse({code: 1, message: 请求方式错误}) def dashboard(request): 可视化大屏页面 return render(request, predict/dashboard.html)6.2 ECharts销量趋势图在可视化大屏中ECharts是最常用的图表库之一。我们通过Django的模板语法向JavaScript传递数据。!-- 文件路径templates/predict/dashboard.html -- !DOCTYPE html html langzh-CN head meta charsetUTF-8 title母婴用品销量分析大屏/title script srchttps://cdn.jsdelivr.net/npm/echarts5.4.3/dist/echarts.min.js/script style body { background: #f5f7fa; font-family: Microsoft YaHei, sans-serif; } .chart-container { display: flex; flex-wrap: wrap; justify-content: center; margin: 20px auto; max-width: 1400px; } .chart-box { background: #fff; border-radius: 8px; box-shadow: 0 2px 8px rgba(0,0,0,0.1); width: 640px; height: 400px; margin: 10px; padding: 10px; } .chart-title { font-size: 20px; text-align: center; margin: 20px 0 10px; color: #333; } /style /head body div classchart-title母婴用品电商销量分析看板/div div classchart-container div idsalesTrend classchart-box/div div idcategoryRank classchart-box/div div idpriceDistribution classchart-box/div div idpredictChart classchart-box/div /div script // 模拟从后端接口获取数据实际项目中可以通过Django视图渲染数据 const salesTrendOption { title: { text: 近30天销量趋势, textStyle: { fontSize: 14 } }, tooltip: { trigger: axis }, xAxis: { type: category, data: [10-01, 10-02, 10-03, 10-04, 10-05] }, yAxis: { type: value }, series: [{ name: 销量, type: line, smooth: true, areaStyle: {}, data: [120, 190, 180, 260, 310] }] }; const categoryRankOption { title: { text: 类目销量排行, textStyle: { fontSize: 14 } }, tooltip: { trigger: item }, xAxis: { type: value }, yAxis: { type: category, data: [纸尿裤, 奶粉, 婴儿服饰, 玩具, 洗护] }, series: [{ name: 月销量, type: bar, barWidth: 20, data: [3200, 2800, 2100, 1500, 900] }] }; // 初始化图表 const trendChart echarts.init(document.getElementById(salesTrend)); const rankChart echarts.init(document.getElementById(categoryRank)); trendChart.setOption(salesTrendOption); rankChart.setOption(categoryRankOption); /script /body /html这段代码使用了ECharts的line和bar两种基础图表。实际项目中可以根据需求扩展为饼图、散点图、热力图甚至轮播大屏。6.3 前后端数据交互方式模板变量的渲染方式虽然简单但在实时更新、异步加载场景中不够灵活。更推荐的方式是Django提供JSON接口前端通过fetch或axios获取数据后再渲染图表。例如上面的predict_sales视图已经实现了JSON接口前端可以直接调用fetch(/predict/api/predict/?price129comment_count800listing_month11category_code1price_level_code2is_promotion1) .then(response response.json()) .then(res { if (res.code 0) { const data res.data; // 将data.pred_sales渲染到页面 document.getElementById(predResult).textContent 预测销量 data.pred_sales 件; } });后端与前端分离的好处是页面改版时不需要修改Python代码接口保持不变即可。7. 爬虫数据入库从CSV到MySQL7.1 通过Django ORM实现批量导入爬虫清洗后的CSV文件可以通过Django的loaddata命令导入也可以编写脚本直接使用ORM批量写入。小型项目中更推荐后者因为可以灵活控制字段映射。# 文件路径goods/import_data.py import pandas as pd from goods.models import Category, Product def import_products_from_csv(csv_path): 将CSV中的商品数据导入数据库 df pd.read_csv(csv_path) # 创建默认类目 category, _ Category.objects.get_or_create(name母婴用品) products [] for _, row in df.iterrows(): product Product( titlerow[title], categorycategory, pricerow[price], stock0, month_salesrow[month_sales], comment_countrow.get(comment_count, 0), is_activeTrue ) products.append(product) # 批量创建效率更高 Product.objects.bulk_create(products, batch_size500) print(f成功导入 {len(products)} 条商品数据)在Django中运行脚本的方式python manage.py shell goods/import_data.py7.2 批量导入的性能注意点如果CSV文件有上万行使用bulk_create比逐条save快得多。但在批量导入之前要考虑主键冲突问题。如果商品链接是唯一标识建议在模型中增加source_id或唯一约束避免重复导入。7.3 数据一致性验证导入完成后可以通过Django shell快速验证数据量python manage.py shellfrom goods.models import Product print(Product.objects.count()) print(Product.objects.order_by(-month_sales)[:10])如果输出正常说明数据已经入库。8. 完整系统联调与运行验证8.1 启动Django服务在项目根目录执行python manage.py runserver 0.0.0.0:8000浏览器访问http://127.0.0.1:8000/products/查看商品列表。访问http://127.0.0.1:8000/predict/dashboard/查看可视化大屏。8.2 数据采集联调流程如果希望整个流程自动化可以编写一个调度入口脚本按顺序执行爬虫、清洗、入库、训练、启动服务。这里给出一个简单的run_all.py示例# 文件路径run_all.py import subprocess import os def run_cmd(cmd): print(f执行命令: {cmd}) result subprocess.run(cmd, shellTrue) if result.returncode ! 0: raise RuntimeError(f命令执行失败: {cmd}) def main(): # 1. 爬取数据 run_cmd(python spider/taobao_spider.py) # 2. 数据清洗 run_cmd(python spider/data_clean.py) # 3. 导入数据库 run_cmd(python manage.py shell goods/import_data.py) # 4. 训练模型 run_cmd(python predict/train_model.py) # 5. 启动服务 run_cmd(python manage.py runserver 0.0.0.0:8000) if __name__ __main__: main()这个脚本在开发阶段已经够用。生产环境中应该使用Celery或APScheduler实现定时任务调度避免频繁手动执行。8.3 预期输出验证运行后如果一切正常应该能看到爬虫脚本打印抓取的商品数量。清洗脚本输出清洗前后的数据量对比。模型训练脚本输出MSE、MAE、R2等评估指标。商品列表页展示出爬取并入库的母婴商品。可视化大屏展示销量趋势和类目排行。9. 常见问题与排查思路9.1 Django启动报错如果启动时出现ModuleNotFoundError: No module named pymysql说明pymysql未安装或未在__init__.py中注册。解决办法pip install pymysql然后在sales_system/__init__.py中加入import pymysql pymysql.install_as_MySQLdb()9.2 中文乱码问题爬虫采集的数据写入CSV时如果使用默认编码Excel打开可能出现乱码。推荐使用utf-8-sig编码df.to_csv(data/output.csv, indexFalse, encodingutf-8-sig)MySQL中建表时也要使用utf8mb4编码否则emoji等特殊字符无法存储。9.3 模型预测结果偏差很大这种问题一般从三个方向排查训练数据是否太少随机森林在样本量较少时效果不稳定。特征是否有区分度如果只使用价格预测销量模型很难学习到复杂规律。是否有异常值月销量极高的爆款商品会拉高整体误差可以考虑剔除或单独建模。9.4 爬虫请求频繁被限制如果目标网站出现滑块验证或限制IP说明请求频率过高或触发了反爬机制。解决方式包括降低请求频率增加随机延时。使用代理IP池需合法合规。模拟浏览器头部信息和Cookie。优先使用官方开放API或已授权的数据源。9.5 数据库迁移失败当出现django.db.utils.ProgrammingError时通常是数据库表结构已经存在但迁移记录与实际模型不一致。解决方式python manage.py makemigrations --empty goods python manage.py migrate goods --fake注意这种方法适用于开发环境生产环境不要轻易使用--fake以免造成表结构错乱。下面是常见问题的汇总表格问题现象常见原因解决思路启动服务报ModuleNotFoundError缺少依赖包按requirements安装依赖中文乱码文件编码未指定UTF-8使用utf-8-sig写入CSV数据库表不存在未执行迁移命令执行makemigrations和migrate模型精度低数据量过少或特征不足增加样本、优化特征工程爬虫被限制请求频率过高控制频率、使用合法数据源预测接口返回0特征顺序不一致核对训练和预测时的特征顺序10. 项目落地的工程建议10.1 代码组织与模块划分课程设计或小项目可以把代码都放在同一个目录下但当你准备扩展成真实项目时建议按业务模块拆分得更彻底一些。例如数据采集部分独立成一个spider服务Django只负责提供Web界面和API模型训练部分则可以用脚本或单独的服务运行。模块解耦能让团队协作更顺畅也让后续维护成本更低。10.2 配置管理数据库密码、API密钥、第三方平台凭证这些敏感信息不要硬编码在代码里。开发阶段可以使用config.py或.env文件生产环境则建议使用环境变量或配置中心管理。10.3 异常处理与日志爬虫和模型训练都属于耗时任务需要详细的日志记录。建议使用Python的logging模块而不是print。import logging logging.basicConfig( levellogging.INFO, format%(asctime)s - %(name)s - %(levelname)s - %(message)s, handlers[ logging.FileHandler(logs/app.log, encodingutf-8), logging.StreamHandler() ] ) logger logging.getLogger(__name__) logger.info(开始爬取数据...)10.4 模型管理训练好的模型文件建议建立版本管理比如sales_rf_model_v1.pkl、sales_rf_model_v2.pkl。当模型效果出现下滑时可以快速回滚到上一个稳定版本。同时在模型中保存训练时间、数据集信息等元数据方便追溯。10.5 数据库备份生产环境中订单表数据非常宝贵。建议每天进行自动化备份# MySQL备份示例 mysqldump -u root -p sales_system backup_$(date %Y%m%d).sql同时在Django后台删除或修改订单数据时要严格遵守最小权限原则不要在生产环境随意执行批量删除操作。10.6 安全边界购物管理系统涉及用户订单必须重视安全。Django自带的安全功能要全部开启CSRF防护。SQL注入防护使用ORM而非拼接SQL。XSS防护模板自动转义。用户密码使用Django内置的加密算法存储。开发阶段调试时可以设置DEBUG True生产环境务必关闭并配置ALLOWED_HOSTS。11. 后续优化方向当前系统已经具备从数据采集到销量预测再到可视化展示的完整闭环但还可以从以下几个方向继续迭代。11.1 预测模型升级随机森林回归是很好的基线模型但如果你想进一步提升预测精度可以尝试XGBoost、LightGBM或Stacking集成模型。同时如果积累了足够长的时间序列数据可以使用Prophet或LSTM来捕捉周期性和趋势性。11.2 智能补货提醒在销量预测的基础上结合库存数据和供应商补货周期可以实现“预测性补货”。比如当预测未来7天销量大于当前库存时系统自动生成补货建议单。11.3 用户画像与个性化推荐母婴用户有明显的人群特征比如孕期、新生儿、幼儿期等不同阶段的购物需求差异很大。基于用户的浏览、收藏、购买行为可以构建简单的用户画像并在商品列表页展示个性化推荐商品。这个方向很适合作为下一步的功能扩展。11.4 实时数据接入如果公司内部有业务中台或数据中台可以通过消息队列实时接入订单数据替代手动运行爬虫。这样销量预测模型可以每天自动更新不用依赖人工干预。12. 写在最后这个Python电商销量分析与预测系统并不算复杂但它把数据采集、数据清洗、Web开发、机器学习建模和数据可视化完整地串了起来。对于初学者来说最大的价值不是某一个算法或某一个框架而是建立“从数据到业务”的整体思维。希望你可以跟着文章把项目跑通再根据实际场景替换数据源、调整模型打造一套适合自己的电商数据分析工具。如果文章对你有帮助欢迎收藏备用也欢迎在评论区交流你在模型训练或爬虫采集中遇到的问题。