采集多页数据时,翻页是最容易出问题的地方。 有人用“循环固定次数”写死10页,商品不够10页就报错;有人一直点“下一页”直到消失,结果卡在最后一页死循环。
3种翻页实现方式:按钮判断法(最通用)、URL拼接法(最快)、滚动加载法(无按钮场景)。
一、按钮判断法:适用90%的分页场景
页面有“下一页”按钮,点完按钮后内容刷新。 核心是判断按钮是否还存在或是否变成禁用状态。
操作步骤
- 捕获“下一页”按钮元素
- 在循环内判断按钮是否存在且未禁用
- 存在就点击,等待新内容加载
- 不存在就退出循环
# 完整翻页流程(以淘宝搜索结果页为例)
# 初始化
设置变量:还有下一页 = True
# 循环翻页
循环条件:还有下一页 == True
# 采集当前页商品(调用子流程)
调用子流程:C01_CollectCurrentPage
# 判断“下一页”按钮是否存在且未禁用
# 方法1:判断元素是否存在(简单但无法判断禁用状态)
判断元素是否存在://a[contains(text(),'下一页') and not(contains(@class,'disabled'))]
存入:下一页可用
如果 下一页可用 == True
点击元素://a[contains(text(),'下一页')]
# 等待新页面加载完成(关键!)
等待元素出现://div[@class='item'],超时5秒 # 用新出现的商品卡片做标志
固定等待:0.5秒 # 额外缓冲
否则
设置变量:还有下一页 = False
输出日志:"已到最后一页"
输出日志:"翻页完成,共采集X页"
判断禁用的常见写法:
# 淘宝/拼多多:下一页按钮有disabled类时不可点
//a[contains(text(),'下一页') and not(contains(@class,'disabled'))]
# 京东:按钮变成灰色span(不再是a标签)
判断元素是否存在://span[contains(text(),'下一页')] # 最后一页时a变span
如果 存在 == True
还有下一页 = False
# 通用写法:检查按钮是否包含“disabled”属性
//a[contains(text(),'下一页')][not(@disabled)]
容易踩的坑: 点击下一页后立即判断按钮,还没加载完就判断,可能误判。必须加“等待元素出现”或固定等待。
二、URL拼接法:最快最稳,但有条件
某些网站翻页时URL会变化,比如:
- 第1页:
https://xxx.com/list?page=1 - 第2页:
https://xxx.com/list?page=2
直接拼接URL跳转,不需要点击按钮,速度快且不会被按钮状态干扰。
适用条件
- URL中明确包含页码参数(如
page=、pageno=、pn=) - 页码参数改变后直接访问能加载对应页内容
- 不需要额外的session或token校验
操作步骤
- 获取当前URL,提取页码参数
- 修改页码数,拼接新URL
- 用“打开网页”指令跳转(同一个标签页)
- 等待页面加载
# 示例:抓取知网搜索结果(URL含page=)
# 初始URL
设置变量:base_url = "https://www.cnki.net/search?q=大数据&page="
设置变量:当前页 = 1
设置变量:总页数 = 10 # 已知总页数,或动态获取
循环条件:当前页 <= 总页数
# 拼接当前页URL
设置变量:当前URL = base_url + {当前页}
# 跳转
打开网页:{当前URL},打开方式=当前标签页
等待元素出现://div[@class='result-item'],超时5秒
# 采集当前页
调用子流程:C01_CollectCurrentPage
# 页码+1
当前页 = 当前页 + 1
如何获取总页数? 从页面元素抓取。
# 获取“共123条,每页20条,共7页”
获取元素文本://span[@class='total-page'] → 存入“总页数文本”
# 用正则提取数字
从文本中提取:{总页数文本},正则表达式"共(\d+)页" → 存入“总页数”
优点: 不受按钮变化影响,速度极快(无需模拟点击)。 缺点: 部分网站URL不带页码(POST翻页)或不支持直接访问。
三、滚动加载法:没有“下一页”按钮怎么办?
小红书、抖音、微博等是无限滚动,滚动到底部自动加载新内容。 没有按钮可点,需要用“滚动到页面底部”+“检测新内容”。
操作步骤
- 先记录当前页面的商品数量
- 滚动到底部
- 等待新内容加载(对比数量变化)
- 重复直到达到目标数量或不再加载
# 小红书笔记无限滚动采集
设置变量:上次数量 = 0
设置变量:连续无新增次数 = 0
设置变量:目标数量 = 50
循环条件:采集到的笔记数量 < 目标数量 且 连续无新增次数 < 3
# 获取当前所有笔记
获取相似元素列表://div[@class='note-item'] → 存入“当前笔记列表”
当前数量 = {当前笔记列表的长度}
如果 当前数量 > 上次数量
# 有新内容,更新记录
上次数量 = 当前数量
连续无新增次数 = 0
否则
# 没有新内容,计数+1
连续无新增次数 = 连续无新增次数 + 1
# 如果还没达到目标,继续滚动
如果 当前数量 < 目标数量
# 滚动到页面底部
滚动到页面底部
# 等待新内容加载(关键)
固定等待:1.5秒
# 可选:等待某个加载提示消失
等待元素消失://div[@class='loading-spinner'],超时3秒
# 退出循环后,当前数量就是实际采集到的笔记数
输出日志:"共采集到{当前数量}条笔记"
判断是否到底的加强版: 滚动多次后没有新内容,且滚动条已到底。
# 检测滚动条是否到底
获取滚动条位置:垂直位置 → 存入“滚动位置”
获取页面高度:→ 存入“页面高度”
获取视口高度:→ 存入“视口高度”
如果 滚动位置 + 视口高度 >= 页面高度 - 10 # 接近底部
# 已到底部
注意: 滚动加载法很费时,社区版30分钟可能不够。建议先设目标数量如50条,达到就停。
四、三种方法对比速查
| 方法 | 适用场景 | 优点 | 缺点 |
|---|---|---|---|
| 按钮判断 | 电商、论坛、传统分页 | 通用性强,稳定 | 需处理禁用/消失判断 |
| URL拼接 | URL带页码参数的网站 | 速度快,不受按钮干扰 | 依赖URL规则,部分网站不支持 |
| 滚动加载 | 小红书、抖音、微博 | 还原真人操作 | 耗时,不易判断是否到底 |
选择决策:
- 有“下一页”按钮 → 按钮判断法
- URL里有
page=且能直接访问 → URL拼接法(优先选) - 无限滚动 → 滚动加载法
五、完整代码示例:混合策略(按钮+URL兜底)
有些网站第一页URL没参数,第二页开始有参数。可以用按钮法为主,但点击失败时切URL法。
# 按钮判断法 + 失败时URL拼接兜底
设置变量:当前页数 = 1
设置变量:继续翻页 = True
循环条件:继续翻页 == True
调用子流程:采集当前页
# 尝试点击下一页
Try
点击元素://a[contains(text(),'下一页') and not(@disabled)]
等待元素出现://div[@class='item'],超时5秒
Catch
输出日志:"按钮点击失败,尝试URL拼接法"
# 获取当前URL,尝试拼接下一页
获取当前页URL → 存入“当前URL”
# 假设URL格式:xxx/page/1.html → 改成2
将文本中的数字替换:{当前URL},把{当前页数} 替换为 {当前页数+1} → 存入“下一页URL”
打开网页:{下一页URL},打开方式=当前标签页
等待元素出现://div[@class='item'],超时5秒
# 检查新URL是否真的变了,没变说明到头
获取当前页URL → 存入“新URL”
如果 新URL == 当前URL
继续翻页 = False
输出日志:"已到最后一页"
当前页数 = 当前页数 + 1
# 安全限制:最多翻50页
如果 当前页数 > 50
继续翻页 = False
输出日志:"达到最大翻页数50,停止"
易错速查表
| 错误现象 | 原因 | 解决方法 |
|---|---|---|
| 最后一页还在点下一页 | 禁用判断不准确 | 加not(contains(@class,'disabled'))或检查按钮是否变成span |
| 翻页后采集的还是旧数据 | 新页面没加载完就采集 | 点击后加“等待元素出现”(新页面的特征元素) |
| URL拼接后页面不变 | URL有重定向或需要token | 改回按钮判断法 |
| 滚动加载死循环 | 到底了还继续滚动 | 加“连续无新增次数”判断,超过3次退出 |
| 社区版时长超时 | 滚动等待时间太长 | 设目标数量,达到即停,不要一直滚 |
推荐资源
- 影刀官方流程市场:搜索“翻页模板”有现成示例可下载
- Chrome插件:Pagination Detector(检测网页分页类型)
- 我的经验:优先用URL拼接法,其次按钮法,最后滚动法。能少点一次鼠标就少一次失败风险。
作者:林焱
本文为《影刀RPA学习手册》系列文章之一,内容源于实操经验的整理与分享。
