尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

Python+Django电商数据分析实战:从爬虫采集到销量预测的完整链路

Python+Django电商数据分析实战:从爬虫采集到销量预测的完整链路 做电商数据分析的人迟早会撞上同一个问题订单表、评论表、流量报表堆在眼前但真正要回答的往往是“下一步怎么办”。库存要补多少下一轮活动的主力品放哪几个差评里集中暴露的问题是什么……如果只靠 Excel 手动透视不是算不出来而是每一次复盘都要把同样的清洗、统计、画图重复一遍。Python、Django、数据分析、爬虫、机器学习这组词放在一起很多人第一反应是“我要做一个大而全的电商数据中台”。但我的判断是这个组合的真正价值不是做出某个漂亮大屏而是帮你把一条从数据采集、清洗、可视化到销量预测的完整流程真正跑通并且下一次可以直接复用。这篇文章不是要把 Django 当 Web 开发框架重新讲一遍而是把它放进一条完整的数据链路里看它如何扮演“项目骨架”的角色。1. 先搞清楚这串工具组合到底解决哪类问题1.1 电商数据分析的三个层次别一上来就追算法很多初学者拿到一个电商数据集第一反应是“我要上一个很厉害的预测模型”。这个方向容易让人忽略一个前提预测只是整条数据链路的最后一环前面还有两层更基础的内容。我把电商数据分析通常按三个层次理解层次要回答的问题典型产物第一层发生了什么昨天的销量是多少哪个品类卖得最好报表、趋势图、排行榜第二层为什么会发生差评集中在什么问题上活动带来的变化有多大归因分析、词云、漏斗分析第三层接下来会发生什么下周哪个 SKU 可能缺货下个周期的销量区间是多少预测结果、补货建议爬虫负责把第一层的数据源补齐Django 负责把这些数据完整地存下来词云和可视化负责解释第二层机器学习模型负责回答第三层。如果一上来就写预测代码结果往往是数据只有几百行字段还缺一半模型训练完也没法解释。更常见的情况是数据源本身不稳定今天跑通明天又断了。所以我觉得把第一层和第二层先做扎实比单独追求算法复杂度更重要。1.2 真正的难点不在单个工具而在把流程固定下来你单独看这几个工具每一个都不算新鲜。Python 做数据清洗pandas 一套组合拳。Django 做 Web 后台和接口社区文档非常成熟。爬虫用 requests BeautifulSoup或者直接调公开 API。词云用 jieba wordcloud。销量预测用 scikit-learn 的回归模型或者试试 Prophet。真正的难点是这些工具如何在同一个项目里协作爬虫抓下来的数据存在哪Django 如何读取训练好的模型怎么被页面调用定时更新任务怎么跑失败之后怎么重试如果这些环节全部靠临时脚本手动跑那这个项目就永远是“一次性项目”。今天拿到一份 CSV跑一遍明天数据更新了再改一次脚本。时间一长你维护的不是一套系统而是几十个不知道能不能跑的脚本。所以这个组合的核心判断是Python 负责数据能力Django 负责把所有环节串成可持续使用的系统。电商数据分析的真正产出不是某一张图而是一套从原始数据进入系统到预测结果输出的完整流程。2. 一条电商数据分析链路应该怎么设计才不只是玩具2.1 数据来源先想清楚哪些数据能要哪些不能碰爬虫是这个项目里最容易出问题的环节不是技术上的问题而是边界问题。做学习和个人项目时我通常建议优先确认三个事情数据源是否有公开 API。如果有优先用 API而不是解析 HTML 页面。数据源是否在自己的店铺后台、自有数据库或明确开放的测试数据内。请求频率是否足够克制。无论目标站点是否限制个人练习都应该把请求间隔设得保守一些不要给对方服务器造成压力。对于你自己的电商店铺最稳妥的数据来源其实是后台导出订单明细、商品明细、售后记录、评价文本。Django 完全可以承担把这些数据导入、存储、建模和展示的工作。如果你确实要练习爬虫建议只在公开测试站点、自己搭建的页面、或明确允许抓取的数据源上操作。用爬虫去绕过登录、模拟身份、批量抓取受保护数据这些事情放在个人博客和技术练习里都不合适。我在项目里一般会把“数据来源是否合规”放在整个链路的第一位数据来源不干净后面所有分析结果都不值得信任。2.2 数据表结构不要按报表设计要按业务事实设计很多新手喜欢把数据设计成一张大宽表商品名称、销量、销售额、评论内容全放在一个表里。这样做在导入 Excel 时很省事但后面做预测和归因时会非常痛苦。我更建议按业务事实拆成几张基础表。比如商品、订单、评论各一张表订单通过外键关联商品评论也通过外键关联商品。# shop/models.py from django.db import models class Product(models.Model): sku models.CharField(max_length64, uniqueTrue) name models.CharField(max_length128) category models.CharField(max_length64, blankTrue) class Order(models.Model): order_no models.CharField(max_length64, uniqueTrue) product models.ForeignKey( Product, on_deletemodels.CASCADE, related_nameorders ) quantity models.PositiveIntegerField() amount models.DecimalField(max_digits10, decimal_places2) order_time models.DateTimeField(db_indexTrue) status models.CharField(max_length16, defaultpaid) class Review(models.Model): product models.ForeignKey( Product, on_deletemodels.CASCADE, related_namereviews ) content models.TextField() rating models.PositiveSmallIntegerField() created_at models.DateTimeField(auto_now_addTrue)这套结构至少有三个好处订单和评论是独立增长的事实数据不会互相污染。查询某品类销量时可以直接通过商品外键关联而不用在一张宽表里筛字段。后续做预测时可以按商品维度聚合出日销量表模型输入更干净。如果原始数据已经埋点或者导出了 CSV可以在 Django 里写一个管理命令把 CSV 解析后逐行插入模型。最好不要直接在数据库里手动粘贴因为后续更新时会失控。2.3 Django 在这条链路里不是后台管理而是“编排层”很多人对 Django 的第一印象是“后台管理 登录注册”。但在电商数据分析项目里Django 的职责更接近一个系统的中枢用 Django ORM 管理商品、订单、评论数据。用 Django Command 封装爬虫、清洗、模型训练等定时任务。用 Django View 或 Django REST Framework 对外提供查询接口。用 Django Admin 做简单的数据校正和人工核对。用模板渲染出趋势图和预测结果页面。这样设计之后数据分析不会停留在 Jupyter Notebook 里。Notebook 适合探索但不适合长期运行。Django 则能让“探索结果”变成“可重复执行的流程”。3. 最小可用方案从爬虫入库到词云图再到预测接口3.1 环境准备先创建一个虚拟环境避免依赖冲突。mkdir ecommerce-analysis cd ecommerce-analysis python -m venv venv source venv/bin/activate # Windows 下是 venv\Scripts\activate建议安装的依赖大致如下Django4.2 requests beautifulsoup4 pandas jieba wordcloud matplotlib scikit-learn joblib djangorestframework然后初始化 Django 项目。django-admin startproject config . python manage.py startapp shop我把项目命名为config业务应用命名为shop。实际项目中你可以按自己的习惯命名但尽量保持一个应用只做一类业务。3.2 用管理命令封装爬虫先跑通一条再扩大不要直接把爬虫逻辑写在视图里。视图层要做的是接收请求、返回结果而不是去抓页面。爬虫逻辑应该放进 Django 的管理命令中这样既可以在命令行手动触发也可以被定时任务调用。下面是一个结构示意# shop/management/commands/fetch_catalog.py import requests from bs4 import BeautifulSoup from django.core.management.base import BaseCommand from shop.models import Product class Command(BaseCommand): help 抓取公开测试页面的商品信息示例 def handle(self, *args, **options): url https://example.com/test-shop/products resp requests.get(url, timeout10) resp.raise_for_status() soup BeautifulSoup(resp.text, html.parser) # 这里只是结构示意具体选择器要以页面实际结构为准 for card in soup.select(.card)[:50]: sku card.get(data-sku) name card.select_one(.name).get_text(stripTrue) category card.select_one(.category).get_text(stripTrue) Product.objects.update_or_create( skusku, defaults{name: name, category: category}, ) self.stdout.write(self.style.SUCCESS(商品数据已更新))执行时只需要python manage.py fetch_catalog这里有一个经验不要一上来就抓全量数据。先抓 50 条确认字段解析正确再逐步放开。如果页面结构发生变化你只需要调整选择器而不是重写整个流程。如果数据源提供了 JSON 接口那更简单直接用resp.json()解析字段就可以了。优先用接口解析能少踩很多 HTML 结构变化的坑。3.3 从订单表到词云图把评论文本变成洞察评论分析是电商项目里投入产出比很高的功能。用户不一定看得懂复杂的预测模型但一个商品的核心槽点词云几乎一眼就能看懂。先从 Django ORM 中取出评论数据转成 pandas DataFrameimport pandas as pd from datetime import datetime, timedelta from django.db.models import Sum, Count from shop.models import Order start datetime.now() - timedelta(days90) daily ( Order.objects .filter(order_time__gtestart, statuspaid) .values(order_time__date) .annotate(salesSum(amount), ordersCount(id)) .order_by(order_time__date) ) df pd.DataFrame.from_records(daily) df.columns [date, sales, orders] df[date] pd.to_datetime(df[date])然后对评论内容做分词和词云import jieba from wordcloud import WordCloud from shop.models import Review text .join(Review.objects.values_list(content, flatTrue)[:1000]) words .join( w for w in jieba.cut(text) if len(w.strip()) 1 and w not in STOP_WORDS ) wc WordCloud( font_path/System/Library/Fonts/PingFang.ttc, # Windows 上换成中文字体路径 width800, height600, background_colorwhite, ).generate(words) wc.to_file(media/review_wordcloud.png)注意词云图必须指定中文字体否则中文会显示成方框。这是一个看起来小但实际上会卡住很多人的问题。3.4 第一个可用的销量预测模型先简单再复杂销量预测不建议一上来就上深度学习。电商日销量数据通常量级不大而且周期性明显先用树模型或统计模型完全够用。下面用历史订单记录生成每日销量并构造几个基础特征import numpy as np import pandas as pd from sklearn.ensemble import GradientBoostingRegressor from sklearn.model_selection import train_test_split import joblib # 假设 df 已经包含 date, sales 两列 df df.sort_values(date).reset_index(dropTrue) df[weekday] df[date].dt.weekday df[day_of_month] df[date].dt.day df[lag_7] df[sales].shift(7) df[rolling_mean_7] df[sales].rolling(7).mean() df df.dropna().reset_index(dropTrue) feature_cols [weekday, day_of_month, lag_7, rolling_mean_7] X df[feature_cols] y df[sales] X_train, X_test, y_train, y_test train_test_split( X, y, test_size0.2, shuffleFalse ) model GradientBoostingRegressor(random_state42) model.fit(X_train, y_train) joblib.dump(model, models/sales_model.joblib)这个模型虽然简单但已经包含了三个关键特征weekday捕获周一到周日的周期性差异。lag_7捕获七天前的同期销量。rolling_mean_7捕获最近一周的销量水平用来平滑短期波动。如果数据包含节假日、促销活动等明显特征可以继续加对应的 0/1 特征。但核心思路仍然是从简单模型开始先跑通流程再观察误差最后决定要不要升级模型。3.5 怎么把预测结果交给 Django 页面模型训练完成后放在models/目录下。Django View 加载模型时要注意加载时机。我一般会使用“懒加载”方式避免每次请求都重新读取模型文件import joblib from django.views.decorators.cache import cache_page from django.http import JsonResponse _model None def get_model(): global _model if _model is None: _model joblib.load(models/sales_model.joblib) return _model def predict_api(request): # 实际使用时应从查询参数或数据库最新汇总中构造特征向量 features [[2, 15, 3200, 3100]] pred get_model().predict(features)[0] return JsonResponse({predicted_sales: round(float(pred), 2)})这是一个非常小的接口但已经具备生产线雏形模型文件独立于 Web 代码接口只负责预测数据准备放在了更前面的环节。如果你希望页面里展示历史趋势和预测曲线可以在前端引入 ECharts 或 Plotly通过接口拉取 JSON 数据后再渲染。Django Template 不是不能做但复杂图表的开发效率可能不如前端图表库。4. 从“能跑”到“能长期维护”中间还差几块拼图4.1 定时更新让数据自己流进来如果每天都要手动执行爬虫和模型训练这套系统就不算真正落地。电商数据分析项目应该加一个定时任务。Linux 服务器上最简单的做法是用 cron0 2 * * * cd /path/to/project /path/to/venv/bin/python manage.py fetch_catalog 0 3 * * * cd /path/to/project /path/to/venv/bin/python manage.py train_model如果任务之间有依赖比如先抓订单再训练模型可以把它们串成一个管理命令# shop/management/commands/update_dashboard.py from django.core.management.base import BaseCommand from django.core import management class Command(BaseCommand): help 执行数据分析完整更新流程 def handle(self, *args, **options): management.call_command(fetch_catalog) management.call_command(fetch_orders) management.call_command(train_model)这样只需要一个 cron 入口任务顺序在代码里可控。比在 cron 里写长串命令更清晰也更容易排查。4.2 日志、异常和重试数据抓取和模型训练这两个环节是非常容易出现网络异常或数据格式变化的。在开发阶段你可以接受程序报错但部署后任何一次未处理的异常都可能导致“看起来啥都没跑”。我的建议是每个管理命令都写日志文件至少记录开始时间、结束时间、处理行数。网络请求需要设置超时时间并对超时和连接错误做异常捕获。爬虫命令要幂等。也就是说同一个命令重复执行不会产生重复数据。模型训练命令要保留历史模型文件。如果新模型效果变差可以快速回滚到上一个版本。这几点不是花架子。它们决定你三个月后还愿不愿意继续打开这个项目。4.3 部署时的隐藏坑字符集、字体、环境变量用 Django 部署数据分析项目除了常规的 gunicorn nginx 之外还有几个容易被忽略的点。中文乱码数据库连接串要指定charsetCSV 文件导入时要统一编码。词云图字体服务器上不一定有中文字体。部署前要确认系统字体目录或者在项目里放一个开源中文字体文件。模型路径不要用相对路径相对当前工作目录最好用settings.BASE_DIR拼出绝对路径。环境变量数据库密码、API Token 等敏感信息不要写死在 settings.py用环境变量管理。这些坑单个看起来都不难但叠加在一起会消耗大量排查时间。5. 排查链路预测不准、图表空白、任务失败先查哪一层5.1 按这个顺序排查不要跳遇到问题我一般按下面这个顺序定位看现象是任务没执行还是执行了但数据没更新是图表空白还是预测结果偏离很大看输入原始数据是否完整日期字段是否有缺失评论内容是否为空请求返回的页面结构是否发生了变化看环境虚拟环境是否激活依赖版本是否一致中文字体是否存在数据库字符集是否正确看参数批量导入的条数限制、模型特征列是否对齐、预测接口是否传入了错误的日期范围。看工具边界Django 版本和数据库版本是否兼容wordcloud 是否支持当前 Python 版本模型特征是否真的符合业务场景这个顺序的逻辑是先把最简单、最容易复现的输入问题排除掉再碰复杂的环境和参数问题。不要一上来就怀疑模型算法。5.2 三个高频问题问题一词云图中文变成方框。先检查font_path是否指向了服务器上真实存在的中文字体文件。可以先在命令行用 Python 直接生成一张测试图排除 Django 上下文的影响。问题二模型预测结果非常离谱。先看训练数据是否干净。常见原因包括历史订单时间字段解析错误、订单状态没有过滤、存在重复导入导致销量翻倍。把训练集打印出来先人工看一眼再谈调参。问题三Django 页面加载很慢。常见原因是每次请求都加载模型文件或者数据库查询没有走索引。模型文件用懒加载和应用级缓存复杂查询加select_related或prefetch_related热点图表用cache_page缓存几分钟响应速度会有非常明显的变化。6. 这类项目的适用边界和我最后的建议6.1 适合谁不适合谁适合的人群和场景不适合的人群和场景个人开发者想学习 Python 全栈数据流程大厂或大型电商的实时百万级数据仓库中小店铺想做销量预测和评论洞察需要千亿级特征工程的推荐系统团队需要把临时分析流程产品化对延迟有严格要求的高并发在线服务学生完成电商数据分析类课设或毕设希望只用一个算法就解决所有业务问题这套方案的数据规模上限取决于你的 Postgres/MySQL 服务器资源和定时任务的频率。它更适合“每天更新一次、预测未来一周销量、给运营做参考”这样的场景。如果你未来要处理更大量级的数据可以先把 Django 里的数据同步到 Spark 或 ClickHouse再在分析模块中做更重的计算。但现在这个阶段Django pandas scikit-learn 的组合已经足够覆盖一个小团队的数据分析需求。6.2 把它当成业务系统来养而不是脚本仓库最后我想回到开头的判断。做电商数据分析最容易高估的是模型的复杂度最容易低估的是整个流程的可维护性。如果你问我什么是一个电商数据分析项目成功的标志我的答案不是模型准确率多高而是当业务方提出“下周每个 SKU 的备货建议是什么”的时候你不需要花两天重新导数据、写清洗脚本和训练模型。因为数据已经在系统里指标口径已经固定模型可以重新训练结果能在几分钟内给出。这才是从“会用 Python 做分析”到“能建设数据系统”的关键一步你不再只交付结果而是交付一条可重复运行的链路。而 Django 在这条链路里的角色就是把那些松散的数据脚本变成有结构、有边界、能被维护的系统。如果你是从零开始我的建议是不要急着写爬虫先用 Excel 或后台导出的订单表建好 Django 数据模型跑通销量趋势和词云图再尝试加预测。把最小闭环跑起来比一次设计出完美架构重要得多。
返回列表