影刀RPA实操指南:懒加载页面采集——滚动加载与index去重
采集一个后台订单列表,页面上明明显示50条数据,用影刀RPA抓回来的却只有十来条,而且每次抓的数量还不一样——这就是懒加载页面的标志性现象。我非技术出身,实操两年多,懒加载是我从"能跑"到"跑得稳"之间最大的一道坎。这篇用官方文档里的经典案例,把滚动加载和index去重的完整方案拆开讲,看完你就能改造成自己的采集流程。
懒加载现象:为什么只抓到一半数据
先搞清懒加载是什么。懒加载是指网页只渲染当前屏幕上显示的元素,屏幕外面的元素在代码里根本不存在。官方文档以聚水潭订单页面为例:一页上明明有50个订单信息,但网页代码里只有16个元素被加载出来;你继续往下滚动,后面的元素会被加载出来,但前面的元素会从代码里消失。
这是懒加载最坑的地方:总有一些元素处于"不显示"状态,你永远无法一次性拿到全部50条。
排查方法很简单:对目标元素点校验,数一数实际校验到的数量和页面显示的数量是否一致。不一致,基本可以断定是懒加载或者虚拟列表。根因是前端为了性能,只保留可视区域附近的DOM节点,屏幕外的统统销毁。
所以修复思路不是"一次抓全",而是"边滚边抓、抓过不重抓"——这就是滚动加载加去重的组合。
滚动加载:让数据先加载出来再抓
滚动本身不难。影刀RPA的网页对象提供鼠标滚动网页指令,可以滚动到底部、顶部或指定位置,还能选瞬间滚动或平滑滚动:
fromxbotimportwebdefmain(args):browser=web.get_active()# 平滑滚动到页面底部,触发懒加载加载新数据browser.scroll_to(location='bottom',behavior='smooth')# location 可选:'bottom' 底部 / 'top' 顶部 / 'point' 指定坐标# 指定坐标时用 top 和 left 参数控制纵横位置不写代码也可以用指令面板里的鼠标滚动指令,在右侧指令详情面板选滚动位置为"底部"。滚动之后要给数据渲染留时间,配合等待元素出现(web)等一个新加载出来的元素,或者等一个固定时长,页面快慢都能兼容。
另一个思路是针对页面内部带滚动条的列表区域:有的列表不是整页滚动,而是列表容器自己滚动,这时要用滚动指定位置的写法,或者用鼠标滚轮指令把光标悬停在列表区域内再滚动。方向搞错了,滚了半天列表纹丝不动。
index去重:解决"前面的元素会消失"
滚动只是让数据出现,真正的核心是去重逻辑。官方文档的方案非常漂亮:先打开F12观察网页代码,发现每个数据行元素都有一个index属性,值从0到49唯一确定,不随滚动位置变化。
于是方案成型:在循环中维护一个"记录列表",无限循环向下滚动,每轮把当前可见的元素循环一遍,用index属性和记录列表比对——记录过的跳过,没记录过的抓取数据并记入列表。当记录列表长度达到50,说明全部抓完,退出循环。
把这套逻辑翻译成影刀RPA的指令骨架:
# 懒加载采集核心逻辑(对应影刀指令组合)page=web.get_active()# 获取已打开的网页对象record_list=[]# 新建列表:记录已抓取行的 index 属性data_list=[]# 新建列表:存放抓取到的业务数据whileTrue:# 无限循环(影刀里的无限循环指令)rows=page.find_all('订单行')# 循环相似元素获取当前可见行forrowinrows:# 对当前可见的行逐个处理idx=row.get_attr('index')# 取该行的 index 属性ifidxinrecord_list:# 已抓过 → 跳过continuerecord_list.append(idx)# 未抓过 → 记录 indexdata_list.append(row.get_text())# 抓取该行数据iflen(record_list)>=50:# 抓满50条 → 退出breakpage.scroll_to(location='bottom')# 没抓满 → 继续向下滚动流程执行结果是打印出0到49全部行且没有重复——官方文档实测验证过的方案,直接照抄就能跑。
没有index属性怎么办:业务字段做唯一键
不是每个网站都贴心地给你index属性。官方文档同样给了替代方案:用页面上原有的业务数据做唯一判断标准,比如订单号、商品编码这类天然不重复的字段。
做法上的差别只有一处:循环到每一行时,不再取index属性,而是把当前循环到的行元素当父元素,通过关联父元素找到它的内部订单号子元素,取文本记入记录列表做判断依据。判断逻辑、滚动逻辑、退出条件完全不变。
选唯一键的标准:全页范围内不重复、滚动前后值不变、取值稳定不报错。订单号、SKU编码、链接地址都符合;商品标题偶尔有同名,慎用;时间戳字段如果显示到秒,也可以当唯一键。
不知道总数怎么退出循环
还有一个现实问题:很多页面你根本不知道一共有多少条数据,没法用"长度达到50"做退出条件。官方的解法很聪明——利用去重逻辑的副产品。
原理是:如果页面已经滚到底,不再有新数据加载,那么每轮循环结束后记录列表的长度不会再增长(因为能见到的都已记录过)。于是退出条件改成:每一轮记录"上一轮结束时记录列表的长度",本轮循环完相似元素后对比,长度没有增加,就说明到底了,退出外层无限循环。
这个方案不依赖任何总数信息,通用性极强。我把它做成了标准模板,小红书搜索结果、抖音商品列表这些没有总数概念的页面全部套用,至今没有翻过车。唯一要注意的是滚动后要等新数据渲染完再判断长度,否则会把"加载慢"误判成"已到底",多加一轮等待或连续两轮无增长才退出的双保险都行。
骚操作:直接改样式让一屏全渲染
官方文档还留了一个大招:既然懒加载是前端样式控制的,那就把样式改了。在聚水潭订单页面打开F12,找到一个id叫_jt_body的元素,它的style属性是height: 1035px; overflow-x: auto;,双击把1035px改成10000px回车——原本只渲染16个元素的页面,50个元素全部校验得到了。
影刀RPA里的做法:捕获这个容器元素,用执行JS脚本指令或设置元素属性的方式,把样式设为height:10000px;overflow-x:auto,然后正常一次抓取全部数据,不用滚动不用去重。
这个方法适合容器高度可控的内部后台,抓一次改一次。缺点是数据量极大时前端可能卡顿,而且页面改版后元素id会变,所以它适合做临时方案,正式长期跑的流程还是推荐滚动加去重的标准方案。
其余核心模块速览:采集流程的知识底座
认识影刀与安装:官网下载,浏览器插件装好是采集的前提,社区版每天30分钟时长对练手够用。
元素定位四合一:懒加载场景下元素捕获要抓可视区内的元素;XPath取index属性做去重键;CSS选择器定位列表容器;正则清洗采集文本。
变量与数据类型:记录列表和数据列表是本方案的骨架,列表的追加、包含判断、长度统计全程使用;字典适合存一行多字段。
流程控制:无限循环加双层退出条件(抓满或不再增长)是标准结构,内层循环相似元素(web),外层滚动判断,Try-Catch防单行异常中断整轮。
网页自动化:滚动、等待、去重都属于网页自动化这个大模块,和窗口切换、弹窗处理叠加使用。
数据处理:抓完写入数据表格再落Excel,写入行数据到表格支持批量,数据量大的用Pandas去重清洗兜底。
鼠标键盘图像:容器内滚动用鼠标滚轮指令配合悬停;无属性控件靠图像识别wait_appear判断加载状态。
进阶技能:懒加载的数据多来自XHR接口,监听网络请求或直接HTTP请求拿JSON,比滚动模拟快得多;Python协同做去重和数据结构化。
平台实战:小红书笔记采集是滚动加载的典型场景,抖音商品列表无限滚动加class哈希变化,聚水潭等ERP后台是容器内滚动的代表。
系统联动:采集完成写飞书多维表格,运行日报推送抓取条数到群机器人,定时任务夜间执行避高峰。
工程化规范:懒加载采集封装成子流程,参数为目标元素和预计条数,去重逻辑模板化复用;命名"平台-懒加载采集"。
易错速查:懒加载采集五个高频坑
- 抓到的数据每次数量不一样 → 页面是懒加载,上滚动加载加记录列表去重
- 滚动后数据没新增就退出了 → 滚动后缺渲染等待,加等待元素出现或双轮无增长才退出
- 去重键偶尔漏数据 → 唯一键选了会重复的字段如商品标题,换订单号或链接
- 列表区域滚动无效 → 滚的是整页不是容器,用指定位置滚动或悬停后滚轮
- 抓完发现抓了重复行 → 记录列表的包含判断漏了,检查index取值时机是否在数据渲染完成之后
学习资源与延伸阅读
官方文档"网页懒加载场景和解决方案"一篇就是本文方案的出处,index去重、订单号替代、无总数退出、改样式四个方案都有完整图文。我把懒加载采集通用模板的完整源码放在代码仓库 home.linyan.cloud,换掉元素和唯一键就能适配你自己的目标页面,可以直接参考改造。
#影刀RPA #RPA自动化 #网页自动化 #数据采集 #懒加载
作者:林焱