Python电商数据分析平台:Django+爬虫+机器学习完整实战 这次我们来看一个典型的 Python 综合性项目电商数据分析平台。它不是一个单独的算法脚本而是把爬虫采集、数据清洗、销量预测、可视化大屏、词云图展示和 Django Web 框架串成一条完整链路的工程。如果你正在做毕业设计、竞赛项目或者想在公司内部搭一套轻量级数据分析后台这个方向覆盖的技术点非常全值得完整跑一遍。先看核心结论项目基于 Django 框架搭建 Web 服务用爬虫获取电商公开数据用 pandas 做清洗和统计用 scikit-learn 训练销量预测模型用 ECharts 做可视化用 wordcloud 生成词云图。整个系统可以通过浏览器访问也能把预测能力封装成 API 接口供其他系统调用。本文不绑定某个具体仓库而是给出一套可直接落地的工程实现思路并给出关键代码示例和验证方法。1. 核心能力速览能力项说明项目类型Python Web 数据分析平台核心框架Django Django REST Framework数据采集requests BeautifulSoup4 / Scrapy数据处理pandas numpy机器学习scikit-learn线性回归、随机森林等可视化ECharts 前端图表 Django JSON 接口词云图wordcloud jieba 中文分词数据库SQLite 或 MySQL按项目需要切换启动方式命令行启动 Django 开发服务器接口能力REST API 返回 JSON可支持销量预测、统计数据查询批量任务Celery Redis 可实现定时采集和批量预测适合场景电商数据分析、销量预测、毕业设计、内部数据看板需要说明的是这个项目的硬件门槛很低普通电脑就能跑。预测模型用的不是大模型而是传统机器学习算法训练数据量在几千到几万条时CPU 即可完成训练。主要内存开销集中在 pandas 读取 DataFrame 和词云图生成阶段。2. 适用场景与使用边界这类项目适合以下几类读者Python 学习者想在一个项目里同时接触爬虫、Web 开发、数据处理和机器学习。数据分析岗位候选人需要一个能展示完整数据流水线的作品而不是只做 Kaggle 练习赛。毕设选题者电商销量预测是经典选题功能边界清晰容易出成果。中小团队开发者需要快速搭建一个内部数据看板把运营数据变成可查询的 Web 页面。项目能解决的问题包括商品销量数据的自动采集与入库。销量趋势的统计和可视化。基于历史数据训练销量预测模型。评论关键词的提取与词云展示。通过 Web 页面和 API 对外输出分析结果。但要明确使用边界。电商数据爬虫涉及版权、隐私和平台规则只允许采集公开数据并且要遵守目标网站的 robots.txt 协议。不要爬取用户个人信息、订单隐私数据也不要对目标站点造成压力。采集频率要合理控制。个人学习和内部研究场景下建议优先使用公开数据集或自己模拟生成数据避开法律风险。涉及商业数据时必须先确认数据来源的授权情况。3. 技术架构与模块设计整套系统的模块职责如下爬虫采集模块 - 数据清洗模块 - 数据库存储 - Django Web 模块 - 前端可视化 |- 机器学习预测模块 - 输出预测结果 |- 词云图生成模块 - 输出图片和词频Django 在这里的角色是 Web 框架和业务调度中心。爬虫采集的数据通过 ORM 写入数据库Django 的 View 对前端提供 JSON 接口机器学习模型在训练完成后被加载到内存中通过独立接口对外提供预测服务。在 Django 项目中建议划分以下 AppApp 名称职责crawler爬虫采集逻辑、数据清洗、入库analysis数据统计、销量预测、词云生成dashboard页面渲染和图表接口apiREST API 接口对外输出数据需要注意的是Django 的 MTV 模式中View 负责业务逻辑Template 负责页面展示。在数据分析和预测场景下建议把耗时操作放到异步任务中执行避免请求阻塞。下一节先解决环境问题。4. 环境准备与前置条件建议使用 Python 3.9 到 3.11 之间的版本。Python 3.12 部分依赖包可能还没有完全适配遇到问题会更麻烦。使用虚拟环境隔离依赖。# 创建虚拟环境 python -m venv venv # 激活虚拟环境 # Windows venv\Scripts\activate # Linux / macOS source venv/bin/activate安装核心依赖pip install django djangorestframework requests beautifulsoup4 pandas numpy scikit-learn wordcloud jieba celery redis如果使用 MySQL 作为数据库还需要安装连接驱动pip install pymysql然后创建 Django 项目和应用django-admin startproject ecommerce_analysis cd ecommerce_analysis python manage.py startapp crawler python manage.py startapp analysis python manage.py startapp dashboard python manage.py startapp api创建完成后在settings.py中注册 AppINSTALLED_APPS [ django.contrib.admin, django.contrib.auth, django.contrib.contenttypes, django.contrib.sessions, django.contrib.messages, django.contrib.staticfiles, rest_framework, crawler, analysis, dashboard, api, ]数据库默认使用 SQLite适合本地开发和测试。如果要切换到 MySQL修改DATABASES配置DATABASES { default: { ENGINE: django.db.backends.mysql, NAME: ecommerce_db, USER: root, PASSWORD: your_password, HOST: 127.0.0.1, PORT: 3306, } }5. 数据模型设计数据模型是整个项目的地基。设计不好后面的分析和预测都会很别扭。核心模型包括商品、销量记录、评论和预测结果。在crawler/models.py中定义商品和销量记录from django.db import models class Product(models.Model): product_id models.CharField(max_length64, uniqueTrue, verbose_name商品ID) title models.CharField(max_length255, verbose_name商品标题) category models.CharField(max_length64, verbose_name类目) price models.FloatField(verbose_name价格) shop_name models.CharField(max_length128, verbose_name店铺名称) created_at models.DateTimeField(auto_now_addTrue) class Meta: db_table product verbose_name 商品 class SalesRecord(models.Model): product models.ForeignKey(Product, on_deletemodels.CASCADE, verbose_name商品) date models.DateField(verbose_name日期) sales_volume models.IntegerField(verbose_name销量) sales_amount models.FloatField(verbose_name销售额) updated_at models.DateTimeField(auto_nowTrue) class Meta: db_table sales_record verbose_name 销量记录 unique_together (product, date)评论表用于词云分析class Comment(models.Model): product models.ForeignKey(Product, on_deletemodels.CASCADE, verbose_name商品) content models.TextField(verbose_name评论内容) rating models.IntegerField(verbose_name评分) created_at models.DateTimeField(auto_now_addTrue) class Meta: db_table comment verbose_name 商品评论生成迁移并建表python manage.py makemigrations python manage.py migrate需要注意如果使用 SQLite整型字段的自动增长不是问题但并发写入能力较弱。如果爬虫采集频率高建议使用 MySQL。数据量不大时 SQLite 也够用关键在于字段设计是否满足后续分析需求。6. 爬虫数据采集模块爬虫模块负责把电商数据变成结构化数据。这里只讨论“公开商品列表和公开评价”这一类数据并且要控制采集频率。最简单的方式是 requests 加 BeautifulSoup。以下是请求公开商品列表页的示例import requests from bs4 import BeautifulSoup def fetch_product_list(url): headers { User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 } response requests.get(url, headersheaders, timeout10) response.encoding utf-8 soup BeautifulSoup(response.text, html.parser) product_nodes soup.select(.product-item) # 选择器需要按实际页面调整 products [] for node in product_nodes: title node.select_one(.title).text.strip() price node.select_one(.price).text.strip().replace(¥, ) products.append({title: title, price: float(price)}) return products注意不同的电商页面 DOM 结构完全不同选择器必须根据实际页面调整。更稳妥的做法是优先使用平台开放的官方 API如果没有再考虑爬虫。爬虫采集必须遵守robots.txt并且请求间隔要合理不要让目标服务器压力过大。采集完成后需要清洗。清洗步骤包括去除空值和重复记录。统一日期格式。将价格、销量等字符串转为数值类型。删除明显异常的数据例如价格小于 0 的记录。import pandas as pd def clean_sales_data(raw_data): df pd.DataFrame(raw_data) df.dropna(inplaceTrue) df.drop_duplicates(inplaceTrue) df[date] pd.to_datetime(df[date]) df[sales_volume] pd.to_numeric(df[sales_volume], errorscoerce) df[sales_amount] pd.to_numeric(df[sales_amount], errorscoerce) df df[df[sales_volume] 0] return df数据清洗的结果保存到数据库def save_products(products): for item in products: Product.objects.update_or_create( product_iditem[product_id], defaults{ title: item[title], category: item[category], price: item[price], shop_name: item[shop_name], } )使用update_or_create可以避免重复数据同时保留更新能力。7. 数据分析与销量预测模块数据进入数据库后先做统计分析再做销量预测。7.1 销量趋势统计通过 Django ORM 聚合查询可以快速统计每日销量from django.db.models import Sum from crawler.models import SalesRecord def get_daily_sales(product_id): records ( SalesRecord.objects .filter(product_idproduct_id) .values(date) .annotate(total_volumeSum(sales_volume)) .order_by(date) ) return list(records)这一步返回的数据可以直接用于前端 ECharts 折线图。统计结果转成 JSONimport json from django.http import JsonResponse def daily_sales_api(request, product_id): records get_daily_sales(product_id) dates [str(item[date]) for item in records] volumes [item[total_volume] for item in records] return JsonResponse({dates: dates, volumes: volumes})7.2 特征工程做销量预测前要先构造特征。常用特征包括历史销量序列的滞后值lag-1, lag-7, lag-30。星期几、是否周末、是否节假日。商品价格。类目。滚动平均和滚动标准差。def build_features(df): df_feature df.copy() df_feature.sort_values(date, inplaceTrue) df_feature[lag_1] df_feature[sales_volume].shift(1) df_feature[lag_7] df_feature[sales_volume].shift(7) df_feature[rolling_mean_7] df_feature[sales_volume].rolling(window7).mean() df_feature[day_of_week] df_feature[date].dt.dayofweek df_feature[is_weekend] df_feature[day_of_week].apply(lambda x: 1 if x 5 else 0) df_feature.dropna(inplaceTrue) return df_feature特征是机器学习模型的上限模型只是逼近这个上限。数据量小的时候滞后特征和星期特征是效果最明显的两个因素。7.3 训练销量预测模型这里用随机森林回归作为示例因为它在小数据集上不容易过拟合且能输出特征重要性方便后面解释。from sklearn.ensemble import RandomForestRegressor from sklearn.model_selection import train_test_split from sklearn.metrics import mean_absolute_error, r2_score def train_sales_model(df): feature_cols [lag_1, lag_7, rolling_mean_7, day_of_week, is_weekend] X df[feature_cols] y df[sales_volume] X_train, X_test, y_train, y_test train_test_split( X, y, test_size0.2, shuffleFalse ) model RandomForestRegressor( n_estimators200, max_depth8, random_state42 ) model.fit(X_train, y_train) y_pred model.predict(X_test) print(MAE:, mean_absolute_error(y_test, y_pred)) print(R2:, r2_score(y_test, y_pred)) return model训练完成后模型需要保存到磁盘避免每次请求都重新训练。import joblib joblib.dump(model, sales_model.pkl)加载模型model joblib.load(sales_model.pkl)预测下一天销量import numpy as np def predict_next_day(model, last_record): features np.array([[ last_record[lag_1], last_record[lag_7], last_record[rolling_mean_7], last_record[day_of_week], last_record[is_weekend], ]]) return model.predict(features)[0]需要特别强调模型预测结果只能作为参考不能作为经营决策的唯一依据。销量受促销、天气、平台流量波动、突发事件等多重因素影响传统机器学习模型只能学习历史规律无法感知未来变化。8. 可视化与词云图展示8.1 Django 集成 EChartsECharts 是一个纯前端图表库通过 CDN 引入即可不需要额外安装 Python 包。在dashboard/templates/dashboard/index.html中引入 ECharts 并请求 Django 接口!DOCTYPE html html langzh head meta charsetUTF-8 title电商数据分析平台/title script srchttps://cdn.jsdelivr.net/npm/echarts5/dist/echarts.min.js/script /head body div idchart stylewidth: 100%; height: 400px;/div script fetch(/api/daily_sales/1/) .then(response response.json()) .then(data { const chart echarts.init(document.getElementById(chart)); chart.setOption({ tooltip: {}, xAxis: {data: data.dates}, yAxis: {}, series: [{ type: line, data: data.volumes, smooth: true }] }); }); /script /body /html这种前后端分离方式的好处是接口可以做复用。页面只是消费者之一移动端或者其他系统也可以调用同一套 API。8.2 词云图生成词云图用于展示商品评论中的高频关键词。需要先对评论文本进行中文分词再生成词云图片。import jieba import wordcloud def generate_wordcloud(product_id): comments Comment.objects.filter(product_idproduct_id).values_list(content, flatTrue) text .join(list(comments)) words .join(jieba.cut(text)) wc wordcloud.WordCloud( font_pathmsyh.ttc, # Windows 建议指定中文字体路径 width800, height600, background_colorwhite ) wc.generate(words) wc.to_file(wordcloud.png) return wordcloud.png中文词云最容易踩的坑是字体问题。默认字体不支持中文会显示成方框。Windows 下可以指定C:\Windows\Fonts\msyh.ttcLinux 下需要安装中文字体比如wqy-microhei。生成词云图后接口可以直接把图片路径返回给前端from django.http import JsonResponse def wordcloud_api(request, product_id): image_path generate_wordcloud(product_id) return JsonResponse({image_url: /static/ image_path})更好的方式是把图片保存到媒体目录然后通过 Django 静态文件服务对外提供。9. 接口 API 与批量任务9.1 REST API 设计使用 Django REST Framework 可以快速把分析结果封装成标准接口。安装并注册后在api/views.py中定义接口from rest_framework.decorators import api_view from rest_framework.response import Response api_view([GET]) def sales_summary(request, product_id): records SalesRecord.objects.filter(product_idproduct_id) total_volume records.aggregate(totalSum(sales_volume))[total] total_amount records.aggregate(totalSum(sales_amount))[total] return Response({ product_id: product_id, total_volume: total_volume, total_amount: total_amount, })在api/urls.py中注册路由from django.urls import path from . import views urlpatterns [ path(summary/str:product_id/, views.sales_summary), ]启动服务后可以直接用浏览器访问http://127.0.0.1:8000/api/summary/1001/返回结果{ product_id: 1001, total_volume: 12345, total_amount: 456789.0 }9.2 批量任务设计如果采集数据量大或者需要定时训练模型建议引入 Celery。Celery 是一个分布式任务队列配合 Redis 作为消息代理可以把爬虫采集、模型训练这类耗时任务放到后台执行。settings.py中配置 CeleryCELERY_BROKER_URL redis://127.0.0.1:6379/0 CELERY_RESULT_BACKEND redis://127.0.0.1:6379/1定义异步任务from celery import shared_task shared_task def run_crawler_task(keyword): # 在这里调用爬虫逻辑 products fetch_product_list(keyword) save_products(products) return len(products)调用任务run_crawler_task.delay(手机)Celery Worker 启动命令celery -A ecommerce_analysis worker -l info批量预测的场景同样可以做成任务队列输入商品 ID 列表后台逐个加载模型并预测最后把结果写入预测结果表前端接口直接读取最终结果。10. 资源占用与性能观察整个项目的资源消耗主要集中在三块爬虫采集阶段内存占用取决于同时请求的并发数同步 requests 方式下占用不高。pandas 数据清洗阶段DataFrame 会一次性把数据加载到内存几万条记录大概占用几十到几百 MB数据量超过百万条时建议改用分块读取。模型训练阶段随机森林训练速度较快几万条训练数据在普通 CPU 上几十秒内完成。如果使用 XGBoost训练速度会更快但需要单独安装。观察项目运行状态的方法# 查看 Django 进程内存占用 ps aux | grep python # 查看系统资源占用 top -p pid如果发现接口响应慢优先检查数据库查询次数。Django ORM 最常出现的问题是 N1 查询比如循环里查数据库。使用select_related和prefetch_related可以大幅减少查询次数。# 错误示例循环中查询数据库 for record in sales_records: print(record.product.title) # 正确示例提前关联查询 from django.db.models import Prefetch sales_records SalesRecord.objects.select_related(product).all()词云生成是 CPU 密集操作jieba 分词在文本量大时可能耗时较长。如果部署在服务器上建议把词云生成放到 Celery 异步任务中前端先显示“生成中”任务完成后刷新图片。11. 常见问题与排查方法问题现象可能原因排查方式解决方案启动 Django 报 ModuleNotFoundError依赖包未安装或虚拟环境未激活检查是否有 venv查看 pip list激活虚拟环境后重新安装依赖爬虫获取不到数据页面结构变化、请求头被识别打印响应文本检查 HTTP 状态码更新页面选择器调整 User-Agent中文词云显示方框缺少中文字体查看字体路径是否存在指定系统可用的中文字体文件销量预测结果偏差很大训练数据量不足、特征构造不合理查看训练集和测试集的 MAE增加历史数据尝试滞后特征和节假日特征数据库表锁死爬虫写入频繁且数据库为 SQLite观察错误日志切换 MySQL或降低写入频率接口返回 500代码异常、数据库连接失败查看 Django 日志修复异常检查数据库连接配置Celery 任务不执行Redis 未启动或队列名称不匹配检查 Redis 是否运行查看 worker 日志启动 Redis重启 worker遇到问题时的第一原则先看日志。Django 开发服务器的终端输出、Celery worker 日志、浏览器开发者工具的 Network 面板这三处信息足以定位大部分问题。12. 最佳实践与使用建议做一个完整的电商数据分析平台不只是把代码跑通还要考虑工程化。以下是几个建议。第一目录结构要清晰。爬虫代码、数据处理代码、模型训练代码、Web 接口代码分开存放不要全部堆在views.py里。可以按照crawler/、analysis/、dashboard/、api/划分。第二配置使用独立文件。数据库连接、Redis 地址、爬虫请求头、模型路径等常量统一放到settings.py或独立的配置文件中不要写死在业务代码里。第三爬虫要加间隔。每请求一次页面至少间隔 1 到 2 秒。这既是对目标站点的保护也是降低被封风险的有效手段。import time import random def fetch_with_interval(url): time.sleep(random.uniform(1, 2)) response requests.get(url, headersheaders, timeout10) return response第四模型训练要可复现。固定随机种子、固定训练集和测试集划分比例、保存模型版本。这样即使数据更新后重新训练也能知道模型的相对变化。random_state 42 X_train, X_test, y_train, y_test train_test_split( X, y, test_size0.2, random_staterandom_state, shuffleFalse )第五接口要做访问控制。如果系统部署到服务器Django 的ALLOWED_HOSTS要配置成实际域名或 IP。API 如果只限内部使用可以通过rest_framework.authentication加 Token 认证。第六数据合规是底线。采集数据前确认数据来源的公开性不采集用户隐私数据不抓取非公开接口不把采集到的数据用于商业用途。对爬虫代码加适度频率限制避免给目标服务器带来压力。13. 总结与下一步整套系统最值得尝试的点是把 Django 和机器学习组合起来让数据分析和预测结果通过 Web 页面跑成一个可交互的工具。对于学习者来说这个项目比单独跑一个 notebook 更有工程感也更接近实际工作场景。第一次跑通时建议按这个顺序验证启动 Django 服务访问首页。用公开数据集或模拟数据写入商品和销量记录表。在页面中查看销量趋势图和词云图。训练一个最小销量预测模型查看评估指标。调用 API 接口确认 JSON 输出符合预期。最容易踩的坑集中在三处爬虫选择器和反爬机制、中文词云的字体问题、预测模型训练集和测试集设置不当导致的过拟合。后续可以扩展的方向很明确把模型换成 XGBoost 或 LightGBM对比效果引入时间序列模型如 Prophet 做更专业的销量预测加入用户行为数据做更精细的 RFM 客户分层或者把可视化页面升级成可筛选、可下钻的交互式仪表盘。如果只是单纯想把销量预测从“能跑”变成“实用”建议先把功夫花在特征上引入节假日、促销、天气等外部特征往往比更换模型提升更明显。整个项目在普通电脑上就能开发测试值得动手搭一遍。建议收藏备用后续再往深做时框架和代码不需要大的改动。