资讯详情

资讯详情

李宁商城销售数据分析系统实战:爬虫到可视化全流程解析

开头先聊点实在的。我最初拿到这个题目的时候第一反应是这不就是爬虫加个图表页面嘛但真正把李宁品牌服装鞋帽商城销售数据分析系统从头到尾做下来才发现最花时间的根本不是写爬虫代码而是后面那一长串数据分析、存储选型、指标定义、可视化对接的工作。这个系统说大不大但麻雀虽小五脏俱全从数据采集到清洗入库再到指标计算和前端展示完整跑通一条数据流水线对理解大数据项目的完整生命周期特别有帮助。如果读者朋友正在做类似的电商数据采集课题或者毕业设计选了爬虫数据分析方向再或者单纯想知道一个真实商城的数据到底怎么变成有价值的经营结论这篇文章应该能给你一条可以直接参考的路径。我会把整套设计思路、爬虫方案、存储选型、分析指标和可视化实现都拆开讲不藏着掖着包括踩过的坑和最后我怎么处理的。1. 需求拆解为什么销售数据分析系统的核心不是分析很多人拿到这个题目第一件事就是去写爬虫我在初期也差点这么干。但是往后推演了两周我就发现如果从一开始不把需求边界画清楚后面会陷入爬了一堆数据但不知道用来干嘛的窘境。所以第一步不是写代码而是把数据分析系统这几个字拆成能落地的具体问题。1.1 三个核心问题卖些什么、卖了多少、怎么卖的我把整个系统的业务需求压缩成了三个问题。第一个问题是李宁品牌在电商渠道到底在卖哪些商品也就是商品结构包括服装、鞋、帽这些二级品类各自有多少SKU在售每个SKU的颜色、尺码、价格区间到底分布在哪。第二个问题是这些商品卖得怎么样这里就需要引入销量、销售额、价格波动、评价数量等量化指标。第三个问题是这些商品是怎么卖的也就是促销方式、折扣力度、是否参与平台活动这些因素对销量的拉动有多大。这三个问题直接决定了爬虫要抓什么字段也决定了分析模块要算什么指标。比如价格对销量的影响这个问题如果你只在爬虫里抓了一个当前价格后面想做分析就会很被动因为商品经常参加满减、打折、秒杀当前价格和实际成交价可能差很远。所以我在需求阶段就想清楚了价格必须抓两个关键值商品吊牌价和实际促销价后续才能计算折扣率这个衍生指标。1.2 数据源边界官方商城和电商平台旗舰店的取舍项目题目写的是李宁品牌服装鞋帽商城听起来是一个独立商城但实际操作上李宁的销售渠道覆盖了官网商城、天猫旗舰店、京东旗舰店、抖音店铺等多个入口。我在设计的时候没有贪多而是把数据源锁定为官网商城和天猫旗舰店这两个信息最全、页面结构相对稳定的渠道。这里有个现实原因天猫旗舰店的商品详情页包含月销量、累计评价、品牌故事、尺码库存等结构化信息非常好抓而官网商城虽然数据更官方但部分接口是异步加载的需要多一步分析XHR请求。两者抓下来的数据字段并不完全一致所以存储层必须设计一个能兼容不同数据源的统一表结构不能这个渠道一套字段、那个渠道一套字段否则后面清洗和统计的时候会把你自己绕晕。1.3 用户角色与功能边界不是做大平台而是做分析工具在需求分析阶段还要明确一个问题这个系统到底是给谁用的是普通消费者看价格还是运营人员做决策还是像我这样为了做毕业设计演示数据流水线能力。我最后定位成面向电商运营分析场景的轻量级数据工具所以系统需要的功能模块就是数据采集、任务调度、清洗入库、指标计算、可视化展示外加一个简单的交互查询界面。功能边界划清楚之后我就没再碰会员体系、订单系统、库存管理这些跟销售数据分析无关的模块。这个取舍很关键很多人做大数据系统容易贪大求全最后什么都想做结果哪个模块都没做好。2. 爬虫采集方案的取舍先搞定稳定性再谈速度爬虫是整个系统的数据入口也是很多人最有兴趣的部分。但要泼一盆冷水电商数据的爬虫难点不在会不会写而在爬几天之后还能不能稳定跑。李宁天猫旗舰店的商品总量大概在几百上千个SKU量级这个规模根本不需要分布式爬虫一台普通机器加好的错误处理就能搞定。2.1 页面结构分析与抓取策略我爬取的时候分了两条线。一条线是列表页用来获取全部在售商品的ID、标题、主图价格、月销量这些概览信息另一条线是详情页用来获取单件商品的完整SKU信息和评价数量。列表页和详情页的信息是有关联的所以我在Redis里维护了一个待抓取队列列表页解析出来的商品ID先进队列消费者线程再从队列里取ID去抓详情页这样比同步抓取灵活很多万一某个商品详情页报错也不会影响整批任务。页面解析这里我用了Scrapy框架加XPath选择器没有用Selenium。原因是电商平台的页面虽然有些字段是JavaScript异步渲染的但核心的商品数据一般都在接口返回的JSON里。用Selenium虽然能模拟浏览器但开销大、速度慢而且特别容易触发风控。我后来直接分析XHR请求找到返回商品数据的JSON接口用requests模拟请求加正确的请求头就能拿到干净的结构化数据解析效率提升了不止一倍。2.2 反爬应对请求头、代理与请求频率的三层控制说句实在话如果你只是爬几百个商品页面而且间隔时间控制得足够长一般不会触发严格的风控。但为了系统能长期稳定运行我还是做了三层防护。第一层是请求头伪装包括User-Agent、Referer、Accept-Language这些常规字段尽量让请求看起来像一个真实用户的浏览器行为。第二层是IP代理池我用的是免费代理加少量付费代理混跑的方式每次请求轮换一个IP。第三层也是最重要的一层是请求频率控制每个请求之间随机延时3到5秒再叠加一点抖动宁可爬得慢一点也不要因为太频繁导致IP被临时封禁。这一块的代码我写得比较朴素但每个细节都有对应的坑。比如请求头如果不带Referer部分接口会直接返回403再比如如果同一个IP在10秒内连续请求超过20次很容易触发滑块验证码。处理这些问题的原则只有一个把爬虫当做一个有礼貌的访客而不是暴力搬运工。2.3 字段设计与数据结构爬虫抓到的字段我最终定了二十多个但核心字段其实就三大类商品基础信息、销售表现、评价相关。商品基础信息包括商品ID、商品名称、标题、品牌、一级分类服装/鞋/帽、二级分类比如跑步鞋、篮球鞋、卫衣、外套等、吊牌价、促销价、折扣率、上架时间。销售表现包括月销量、累计销量、库存状态有货/无货、是否参与促销。评价相关包括累计评价数、好评率、评价标签词云。这里要特别提醒商品分类字段是最容易乱的。李宁的商品命名规则经常混入篮球系列跑步系列中国李宁这种系列名而不是标准的品类名。所以我额外建立了一个分类映射表在清洗阶段根据商品标题关键词把商品归入统一的二级分类体系。比如标题里出现跑步就归到跑步鞋出现卫衣就归到卫衣这个映射规则要不断迭代补充才能保证分类准确率。3. 数据管道设计清洗、去重、统一口径才是重头戏爬虫跑起来之后数据就开始源源不断地落进来。但这时候的数据质量是非常糟糕的价格字段可能是字符串、销量可能带万字单位、同一件商品在不同渠道可能被重复抓取、部分商品下架了但旧数据还在库里。如果这些脏数据不处理后面所有分析都是空中楼阁。3.1 数据清洗的几个高频问题我遇到的第一类问题是格式不统一。比如月销量字段有的页面显示3000有的显示1.2万还有的直接是暂无销量这些值必须先转化成统一的数字格式才能参与计算。第二类问题是价格维度混乱促销价字段有时候会和到手价混淆因为平台会显示满减后的预估到手价。我只认详情页结构化数据里明确标记的价格字段不用页面展示层的文本去解析价格。第三类问题是重复数据。因为爬虫是周期性运行的同一个商品ID每次采集都会生成一条新记录如果不做去重分析的时候同一个商品会被统计好几次。我的方案是建立以商品ID和采集日期为联合唯一键的规则同一天内重复采集直接覆盖跨天采集则保留历史快照。这样既能保证同一时刻的数据唯一又能保留时间维度上的变化趋势。3.2 大数据存储选型的真实考量别被Hadoop绑架既然题目叫大数据技术很多人就理所当然地上Hadoop、Spark、Hive这一套。但我得说句实话几百个商品、上万条采集记录这个数据量级用HDFS纯属杀鸡用牛刀。真正合适的是混合存储方案MySQL存清洗后的明细数据和指标计算结果Redis存待爬取队列和缓存热点数据Hive这个组件可以保留但只做周期性的全量归档和离线分析。我的选择是MySQL加Hive两套并行MySQL负责支撑Web展示层的实时查询因为交互页面需要秒级响应MySQL索引优化后完全没问题Hive负责跑一些周期性的复杂分析比如按月统计每个品类的销量趋势、计算价格弹性这类需要全量扫描的任务。这样既满足了题目对大数据技术的要求又保证了系统的实际运行效率。3.3 清洗工具链Pandas做轻量处理脚本做定时调度清洗环节我主要用Pandas做DataFrame级别的处理。整个流程是爬虫写入的原始数据先进一张staging表然后由一个清洗脚本定时读取staging表经过缺失值填充、格式转换、分类映射、去重之后写入最终的dwd明细表。这个流程里有一个很重要的设计原始数据表和分析用明细表分离。原始数据表是照单全收的不管字段多脏都先存下来方便回溯排查而分析用明细表只保留经过清洗、格式统一、口径一致的数据。这样即使清洗规则写了Bug原始数据还在可以重跑清洗任务不至于数据源永久污染。4. 分析指标体系设计从数据到经营结论的翻译层系统最终的价值体现在分析模块。但分析模块不是把爬到的字段直接图表化就完事了而是要把原始字段翻译成有业务含义的指标。我花了不少时间在指标定义上这一节讲清楚我到底定义了哪些指标以及每个指标对应的分析场景。4.1 商品结构分析品类、SKU数量与价格带分布第一个分析模块是商品结构分析。核心指标包括在售商品总数、各二级品类的SKU占比、每个品类的价格带分布、平均吊牌价和平均促销价。这些指标回答的问题是李宁目前的主力品类是什么每个品类的价格区间集中在哪个段位高端线和大众线的占比是否合理。做这个分析的时候我用了不少分组聚合SQL。比如价格带分布这张图我把0到200元、200到400元、400到800元、800元以上分成四个区间分别统计每个区间内的SKU数量然后用堆叠柱状图展示。这个分析的价值在于可以很直观地看出品牌在不同价格带的商品供给强度比如价格带集中在200到600元说明走的是大众运动消费路线如果有大量800元以上的SKU则说明在布局高端产品线。4.2 销售表现分析月销量、销售额与单品排行第二个模块是销售表现分析。核心指标包括月销量Top20商品榜单、销售额Top10品类、平均月销量、高销量商品的价格特征、折扣力度对销量的影响。这里有一个关键点天猫旗舰店显示的是月销量而累计评价数是另一个有参考价值的指标两者结合可以判断一款商品是长期畅销还是短期爆款。我在这块还做了一个比较有意思的分析叫折扣敏感度分析。做法是计算每件商品的折扣率然后看折扣率与月销量的相关系数。结果显示折扣率在五折以下的高折扣商品月销量普遍高于七八折的商品这说明李宁在线上渠道的价格敏感度相当高促销活动对销量有显著拉动。这个结论虽然听起来像常识但用真实数据分析出来的说服力和拍脑袋完全不一样。4.3 评价数据分析从好评率到用户关注点第三个模块是评价数据分析。累计评价数和好评率是直接抓到的字段但要做深入一点就需要对评价关键词进行简单的情感分类。我没有上复杂的NLP模型而是用了一个词频统计加人工规则的方案先把评价标签里出现的高频词统计出来再把舒适好看尺码正做工好物流快这类的关键词分类成质量、外观、尺码、服务几个维度。这块数据虽然粗但能看出不少东西。比如在鞋类商品中尺码偏小的频率如果明显偏高就可以给选品和库存管理提供参考再比如某款商品的好评率明显低于品类均值那可能需要去看评价详情定位具体问题。评价数据的分析价值不在于多么高深的算法而在于把非结构化的文本转化成能指导业务的结构化判断。5. 可视化与系统的一体化实现从数据分析结果到可交互页面分析结果如果只停留在表格里说服力会大打折扣。所以我做了一个可视化展示模块把前面算好的指标以图表形式呈现出来。技术选型是Flask加EChartsFlask负责提供接口和页面渲染ECharts负责图表展示。5.1 后端架构与接口设计后端我用Flask搭了一个轻量级服务提供两类接口一类是页面路由直接渲染HTML模板另一类是数据接口返回JSON格式的图表数据。数据接口从MySQL查询清洗好的dwd表按前端传过来的筛选条件做聚合然后返回给ECharts渲染。接口设计上我遵循了一个图表一个接口的原则每个接口的职责很单一。比如api/sales_trend负责返回销量趋势折线图的数据api/category_distribution负责返回品类占比饼图的数据api/price_band负责返回价格带分布柱状图的数据。这样前后端联调非常顺畅也不容易出现一个接口改坏了另一个图表的情况。5.2 前端图表布局与交互设计前端页面我分了三块看板。顶部是总览卡片显示在售商品总数、总销量、平均折扣率、总评价数这几个核心数值。中间是趋势区放销量趋势折线图和品类占比环形图。底部是明细区放Top20商品榜单表格和价格带分布图表格支持按品类和价格区间筛选。交互设计上做了一个联动筛选器用户可以按一级分类服装、鞋、帽和二级品类跑步鞋、篮球鞋、卫衣等来筛选所有图表的数据范围。这个筛选器在ECharts里其实不用额外写复杂的联动逻辑只需要在筛选器变化的时候重新请求后端接口用新的筛选条件刷新图表数据。5.3 定时调度与全链路自动化爬虫采集和分析计算不能每次都靠手动跑所以我在系统里加了定时调度任务。爬虫任务每12小时跑一次清洗任务在爬虫任务结束后自动触发分析计算任务每天凌晨跑一次全量指标汇总。调度这块我用的方案比较简单是系统的crontab加Shell脚本配合Python脚本的日志输出每次跑完都能看到清晰的执行记录。自动化链路跑通之后整个系统的运转逻辑就变成定时采集、自动清洗、按需分析、可视化展示人工只需要在Web页面上查看结果不用再碰命令行。这个完整闭环对系统化的理解帮助很大你会看到数据从源头是怎么一步步流动到最终的用户面前的这就是数据工程的核心思维。6. 踩坑复盘与后续扩展几个让我记忆深刻的教训整个系统从零到一做完踩了不少坑。挑几个最有代表性的说一下这些在官方文档和教程里基本查不到全是实际操作换来的经验。6.1 请求频率设置不当导致的IP封禁第一次用Scrapy写爬虫的时候并发设置过于激进DOWNLOAD_DELAY没设CONCURRENT_REQUESTS设到了16结果爬了不到五分钟IP就被平台临时限制了返回的全是验证码页面。这个教训让我意识到电商反爬的判定通常不是看单次请求频率而是看一段时间内的请求密度和模式。后来我把并发降到4每个请求间隔随机延时3到5秒再配上代理池就再没出过问题了。6.2 分类字段混乱导致的分析结果失真另一个记忆深刻的坑是分类字段。李宁的一些联名款和系列款商品标题里会写着中国李宁韦德之道反伍等系列名但这些不是品类名。第一版清洗脚本我没做归一化导致鞋这个一级分类下面出现了二十多种二级分类分析图表的可读性直接崩溃。后来我建了一张关键词映射表把韦德驭帅闪击映射到篮球鞋赤兔飞电映射到跑步鞋加上人工验证分类准确率才稳定在95%以上。6.3 历史数据快照的缺失造成趋势分析困难还有一个差点踩进去的坑如果爬虫每次都把相同商品的数据做成覆盖更新那价格趋势分析和销量趋势分析就完全做不了因为历史价格和销量快照被新数据冲掉了。我在第一周跑数据的时候就意识到这个问题马上调整了入库策略原始数据表保留每次采集的快照明细表按商品ID加采集日期做主键。这样既保证了页面展示的是最新数据又能用SQL查历史的采集记录做趋势分析。6.4 后续扩展思路从单机到分布式从电商数据到全渠道如果你想在这个项目基础上继续扩展我建议关注两个方向。第一个方向是数据规模的扩展如果要从单渠道几百个商品扩展到多平台几万甚至几十万商品单机爬虫就不太够用了可以考虑引入Scrapy-Redis做分布式调度把待爬队列放到Redis里多台机器同时消费。存储端也可以把Hive的使用频率提上来用分区表按日期归档历史数据降低MySQL的存储压力。第二个方向是分析深度的扩展。当前的情感分析还是基于关键词规则的如果要更精准地理解用户评价里的情绪可以引入预训练的文本分类模型做aspect-based sentiment analysis把舒适包裹透气这些属性粒度的情感值拆出来做成商品优化建议。另外一个可以深入的方向是价格弹性建模结合历史价格和销量数据拟合价格需求曲线给定价策略提供量化参考。最后再分享一个小技巧数据系统的排错思路一定要分层排查。采集层出了问题就看原始数据表的更新时间和采集日志分析层出了问题就看dwd明细表的数据质量可视化层出了问题才去看接口返回的JSON。把自己当成数据流水线上游的一位流水线工人出了问题先确定是哪一段传输带停转了再去对症处理效率会高很多。
觉得有用,分享给同行:

为您的企业打造数字门面

稳重轻奢商务风格,端正雅致视觉,长效耐看不易过时。

立即咨询 →