☰
影刀RPA新手教程:唯品会商品采集实战——品牌特卖数据采集与价格分析
2026/10/5 6:27:41 网站建设 项目流程

影刀RPA新手教程:唯品会商品采集实战——品牌特卖数据采集与价格分析

为什么选唯品会

唯品会的品牌特卖页面结构特殊:商品列表按品牌分区,每个品牌区块内是横向滚动的商品卡片。商品详情页的价格分原价和折扣价两处显示,库存信息不在页面DOM里,藏在接口返回的JSON中。你如果按常规思路"捕获元素→循环相似元素→获取文本",大概率拿不全数据。

这篇不绕弯子,直接从实际踩坑的经验出发,把一个完整的唯品会商品采集+价格分析+飞书通知流程拆给你看。

安装影刀RPA直接去 home.linyan.cloud 看教程,装完打开编辑器新建一个PC自动化应用,下面开始敲流程。

元素定位:先搞清楚你要抓什么

唯品会品牌特卖列表页的结构长这样:每个商品卡片是一个li节点,商品名称在p.title里,原价和折扣价分属两个不同的span,而且原价标签和折扣价标签的class名一模一样,区别在于位置——原价是第一个span,折扣价是第二个。

常规做法是用"获取相似元素列表(web)"批量抓取文本,但这里踩第一个坑:两个价格class同名,获取元素文本时会拿到两个值,影刀返回的是一个列表。正确的做法是不抓文本,先抓元素对象,再用"在元素上执行JavaScript"分别取innerText分割后的第0个和第1个元素。

JavaScript这样写:

function(element,input){vartexts=element.innerText.split('\n');returntexts[0];// 原价![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/780f6ddffecf47458718992aa9bbea7c.png#pic_center)}

折扣价同理,把texts[0]换成texts[1]。注意唯品会的价格格式包含¥符号,后面做折扣率计算时要先去掉¥再转数字。

商品图片的src在img标签里,但唯品会做了懒加载——首屏外的图片src是一个占位图。真实图片地址在data-original属性里。正确做法:获取data-original属性的值,如果为空再取src。

function(element,input){returnelement.getAttribute('data-original')||element.src;}

变量设计:别临时起名

流程写大了,变量名一乱后面根本改不动。这个项目涉及的数据结构:

  • 商品列表:字典列表,每个字典存一条商品数据。影刀里用"新建列表"创建,用"添加字典到列表"追加数据。
  • 品牌名称:字符串,从页面标题或分类标签获取。注意唯品会的品牌名有时带"品牌特卖"后缀,用"文本_替换"去掉。
  • 折扣率列表:浮点数列表,存每条商品的折扣率计算结果。

关键点:影刀的数据类型分字符串、整数、浮点数、列表、字典。从网页获取的文本永远是字符串,做数值计算前必须用"文本_到数字"转换,否则If条件判断折扣率 < 0.5会直接报类型错误。

踩坑:用"获取元素文本"拿到的是"¥299.00",直接文本_到数字转不了——¥不是数字字符。先文本_替换("¥", "")再去掉首尾空格,才能转。

流程控制:循环要能退出

主循环逻辑:

For 每个品牌分类 in 品牌特卖首页 进入品牌页面 While True 滚动鼠标滚轮(向下5次,每次间隔800ms) 获取当前可见商品卡片列表 For 每个卡片 in 商品卡片列表 提取商品名称 → 提取原价 → 提取折扣价 → 提取库存 If 商品名称 不在 已采集列表 追加到商品列表 追加名称到已采集列表 If 已采集列表长度 不再增长 Break 回到品牌分类列表

几个容易忽略的点:

一、While True是无限循环,退出条件靠内部Break。必须确保Break条件能被触发,否则流程跑到天荒地老。判断"列表长度不再增长"的写法:在循环外用变量上一轮长度 = 0,每轮结束比较当前列表长度 == 上一轮长度,如果相等说明页面到底了或没有新数据了,Break。不等就更新上一轮长度 = 当前列表长度。

二、唯品会的品牌特卖页是分页加载的,翻页不是点"下一页"按钮,而是滚动到底部会自动加载。所以流程里是滚动+判断,而不是点击翻页。滚动时注意间隔不能太短,800ms是实测稳定值,低于500ms唯品会的反爬会弹验证码。

三、条件判断用影刀的"If"指令。If的条件表达式里,A == B是判等,A in B是判断A是否在列表B中。这里用商品名称 in 已采集列表做去重判断。

网页自动化全流程

步骤1:打开唯品会首页

用"打开网页"指令,URL填唯品会品牌特卖入口。影刀会自动唤起Chrome浏览器(需要先安装影刀浏览器插件)。

步骤2:等待页面加载

用"等待元素(web)"等待商品列表的父容器出现。不要用固定延迟延迟执行(5000),因为网络波动时5秒不够。等待元素可以设超时30秒,超时走异常处理分支。

步骤3:处理弹窗

唯品会打开后大概率弹登录窗。关闭方案:先尝试按Esc键(用"发送快捷键"),等1秒,如果弹窗还在,用"点击元素(web)"点弹窗右上角的关闭按钮。关闭按钮的X元素是span.icon-close,注意有时候这个X被遮挡,点不到——这时用"在元素上执行JavaScript"直接element.click()绕过遮挡。

步骤4:循环品牌分类

品牌分类按钮是相似元素组,用"获取相似元素列表(web)"拿所有品牌链接元素的href属性。对href列表循环,每个循环项用"打开网页"逐个打开——不要在当前标签页跳转,而是新标签页打开,目的是保留品牌分类页作为后退锚点。每处理完一个品牌,关闭当前标签页,回到分类页继续下一个。

步骤5:滚动加载+数据抓取

进入品牌详情页后,核心是滚动加载。用"鼠标_滚轮"指令,参数填滚动次数=5, 滚动方向=向下,每次滚动后等页面渲染。然后用"获取相似元素列表(web)"抓当前可见商品。

步骤6:翻页判断

不是所有品牌都有大量商品,有些品牌只有一页。判断标准:如果连续两次滚动后获取到的相似元素数量没有变化,说明加载完毕。

数据处理:Excel写入与折扣计算

影刀的数据表格区域就是Excel。用"写入行到Excel"逐条写入,或者等全部采集完用"批量写入Excel"一次性写。

推荐分批写入,因为如果需要中断重跑,已经写入的数据不会丢。分批写的话,每采集完一个品牌就写入一次Excel。

Excel写入时注意表头:第一行写表头["品牌","商品名称","原价","折扣价","库存","活动时间","采集时间"],从第二行开始写数据。

折扣率计算:

折扣率 = (原价 - 折扣价) / 原价

在影刀表达式里写成:

折扣率 = (原价 - 折扣价) / 原价

计算完后用文本_格式化("折扣率 = {:.2%}", 折扣率)转成百分比显示。

一个常见bug:如果原价为0(有些商品没有原价),除以0会报错。数据库存之前先判断If 原价 != 0再计算,否则折扣率直接填N/A。

价格趋势分析不复杂——把数据按采集时间排序,用影刀的"数据表格_排序"按"折扣率"升序排列,TOP10就是降价最狠的商品。如果有历史数据(之前采集的Excel),可以用"Excel_读取区域"加载历史数据,用VLOOKUP匹配商品名称对比价格变化。

鼠标键盘操作细节

唯品会页面上的下拉刷新、横向滚动等操作靠鼠标。

横向滚动商品卡片:先定位到品牌区块的元素对象,用"获取元素位置"拿到top和left,然后用"鼠标_移动"把光标移动到列表区域,再用"鼠标_按住左键"+“鼠标_移动(横向偏移-200)”+"鼠标_松开左键"模拟拖拽。

踩坑:品牌区块的高度不是固定的,有些品牌卡片多有些少,直接用固定坐标可能点到其他品牌。做法是先获取目标品牌标题元素的位置,以此作为基准偏移计算。

快捷键方面:Ctrl+C复制不了网页上鼠标选中的文本,这是影刀浏览器插件的限制。需要复制的话用"获取元素文本"替代。

进阶:网页监听拿接口数据

前面提到库存不在页面DOM中,藏在接口返回的JSON里。找这个接口的姿势:

F12打开开发者工具 → Network标签 → XHR筛选 → 在页面上操作触发数据加载 → 看哪个请求的Response里有商品列表。

唯品会的商品列表接口通常包含vip.com/product/list或类似路径,返回的JSON里data.list是商品数组,每个商品的stock或inventory字段就是库存。

用影刀的"开始监听请求"+"获取监听结果"拿数据:

  1. 开始监听请求,URL填接口路径的模糊匹配(如*product/list*)
  2. 打开品牌页面
  3. 获取监听结果
  4. 解析JSON中的stock字段

监听返回的body是字符串,用"json_解析"转成字典对象后才能用dict["data"]["list"][0]["stock"]的方式取值。注意JSON解析失败一般是body里混入了HTML标签或特殊字符,先打印body看看格式正不正常。

飞书通知:降价自动推送

采集完数据、算完折扣率之后,筛选出折扣率低于5折的商品,推送到飞书群。

飞书通知三步走:

创建机器人:飞书群 → 群设置 → 群机器人 → 添加自定义机器人 → 复制webhook地址。安全设置里如果选了"签名校验",需要把密钥一起填到影刀的飞书群通知指令里。

构造消息:消息内容用变量拼接,格式如下:

商品降价监控报告 采集时间:{当前时间} 品牌:{品牌名称} ------------------------ 商品:{商品名称} 原价:{原价} 折扣价:{折扣价} 折扣率:{折扣率}

发送:用影刀的"飞书群通知"指令,消息类型选"文本"。如果需要@人,在消息内容里加<at user_id="ou_xxx">名字</at>。

踩坑:webhook地址有调用频率限制,一分钟不超过20条。如果一次通知的商品太多,不要每条商品发一条消息,应该把所有商品汇总成一条消息发送。汇总写法:在循环中把所有降价商品信息拼成一个大字符串,循环结束后一次性发送。

定时执行与工程化

流程写完不是结束,要让它自己跑起来。

计划任务设置:影刀控制台 → 计划任务 → 新建任务 → 选择应用 → 设置定时规则。参数说明:

  • 触发时间:建议每天上午10点(唯品会一般上午更新价格)
  • 重试策略:失败重试3次,间隔5分钟
  • 失败通知:勾选飞书群通知,出错了马上知道

异常处理:整个流程最外层包一个"Try-Catch"。Catch里做三件事:截屏保存现场、发送错误信息到飞书群、关闭所有浏览器进程(taskkill /f /im chrome.exe通过"执行命令行"指令),避免下次运行时有残留浏览器窗口。

变量命名规范:前缀标识类型。str_前缀是字符串,list_前缀是列表,dict_前缀是字典。比如list_商品数据、str_品牌名、dict_当前商品。这样三个月后回头看,一眼知道变量是什么类型。

日志:用"打印日志"指令在关键节点输出状态。“开始采集品牌:{品牌名}”、“已采集{数量}条”、“开始发送飞书通知”。出问题看日志就能快速定位到哪一步。

速查表/常见报错

报错信息原因解决
AttributeError: 'NoneType' object has no attribute X元素没找到,变量是None检查元素是否加载完成,加等待元素指令
Can not convert Array to String把列表当字符串用了列表取索引[0]或用join拼接
元素不可见/不可点击元素被弹窗遮挡或滚动位置不对先滚到元素位置再点击
JSON解析失败接口返回的不是纯JSON打印body查看实际内容,可能混了HTML
飞书通知发送失败webhook过期或被限流检查webhook地址,确认一小时内未超20条
chrome.exe进程残留流程中断后浏览器没关Catch里加taskkill /f /im chrome.exe
获取元素文本拿到空白元素是懒加载的,文本还没渲染滚动到元素附近触发渲染,等800ms再取

还有一个小技巧:唯品会的商品链接有时效性,采集下来的URL大概72小时后失效。如果需要长期追踪,不要存URL,存商品ID(从URL中截取spu_id后面的那串数字),需要查看时用https://detail.vip.com/detail-{商品ID}.html拼接。

另一个注意点:唯品会的页面在双11/618期间会加CDN缓存和限流策略,平时能跑通的流程在大促期间可能被拦截。建议大促期间把滚动间隔从800ms改成1500ms,滚动次数从5次改成3次,降低单次请求密度。

内容标签:唯品会RPA采集、商品数据抓取、价格监控、折扣率分析、飞书通知
作者:林焱

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

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

立即咨询