影刀RPA数据采集进阶:分页翻页、懒加载、反爬虫应对全解析
影刀RPA数据采集实战进阶:分页翻页、懒加载、反爬虫应对全解析
作者:林焱|更新时间:2026-06|难度:中级进阶|阅读时间:约16分钟
前言
做数据采集,新手阶段能采集单页数据,进阶阶段要面对这些挑战:
- 数据有几十页,翻页规律各不相同
- 页面用了懒加载,不滚动看不到数据
- 服务器检测出是爬虫,直接封IP
- 验证码突然弹出来,流程中断
本文专注讲这些实际踩坑场景的解决方案,不说基础,全是干货。
第一章:翻页策略全解析
1.1 翻页类型识别
采集之前,先判断翻页类型:
| 翻页类型 | 识别方式 | 典型网站 |
|---|---|---|
| URL参数翻页 | URL里有?page=1或?p=1 | 电商、新闻 |
| 按钮翻页 | 有"下一页"按钮或数字页码 | 通用 |
| 无限滚动 | 滚动到底部自动加载 | 微博、抖音评论 |
| 加载更多 | 点击"加载更多"按钮 | 论坛、部分资讯站 |
| 前端路由翻页 | URL的hash变化(#page2) | SPA应用 |
1.2 URL参数翻页(最简单)
采集目标="https://shop.example.com/products?category=digital&page={page}"总页数=50# 先手动确认总页数,或用代码获取遍历1到 总页数aspageNum:# 构造URLurl=采集目标.格式化(page=pageNum)# 打开页面访问URL:url 等待元素出现://div[@id='product-list']超时时间:15秒# 采集当前页数据[video(video-z4X2ML2s-1782025018282)(type-csdn)(url-https://live.csdn.net/v/embed/525010)(image-https://v-blog.csdnimg.cn/asset/f4faa587144cb7070f19e8b36813806b/cover/Cover0.jpg)(title-店群矩阵自动化突破运营极限!)]调用子流程:ExtractProducts 输出:pageData# 保存数据如果 pageData 不为空:批量写入Excel:pageData# 友好延迟(防止被封)等待:随机(1000,3000)毫秒# 1-3秒随机等待# 打印进度记录日志:"已完成第 "+pageNum+"/"+总页数+" 页"动态获取总页数:
访问URL:首页URL 等待页面加载# 方式1:从页码导航获取总页数总页数文本=获取文本://span[@class='total-page']# 文本格式: "共50页" 或 "1/50"总页数=提取数字(总页数文本)# 方式2:获取页码列表的最后一个所有页码=获取元素列表://ul[@class='pagination']//a[@class='page-num']最后一个=所有页码[-1]总页数=整数(获取文本(最后一个))1.3 按钮翻页(最通用)
页码=1循环:# 采集当前页调用子流程:ExtractCurrentPage 输出:pageData 记录日志:"第 "+页码+" 页,获取 "+len(pageData)+" 条数据"批量写入Excel:pageData# 检查是否有下一页下一页按钮=检查元素是否存在://a[contains(text(),'下一页')]或//button[@aria-label='下一页']或//li[@class='next'andnot(contains(@class,'disabled'))]如果 下一页按钮 不存在:记录日志:"已到最后一页,采集完成"跳出循环# 点击下一页点击:下一页按钮# 等待新内容加载# 方法:等待URL变化 或 等待原来的内容消失等待URL变化 或 等待:2000毫秒 等待元素出现://div[@class='product-item']超时时间:15秒 页码+=1等待:随机(800,2000)毫秒处理页码按钮失效(disabled)的情况:
下一页按钮=找到元素://a[text()='下一页']如果 下一页按钮 存在:按钮class=获取属性:下一页按钮,class如果"disabled"在 按钮class或"inactive"在 按钮class:记录日志:"下一页按钮已禁用,到达最后一页"跳出循环 点击:下一页按钮1.4 无限滚动加载
已采集数量=0上次数量=-1连续无变化次数=0循环:# 滚动到底部,触发加载执行JS:"window.scrollTo(0, document.body.scrollHeight)"等待:2000毫秒# 等待新内容加载# 等待加载指示器消失(如果有)如果 存在(//div[@class='loading-spinner']):等待元素消失://div[@class='loading-spinner']超时时间:10秒# 统计当前数量当前元素列表=获取元素列表://div[@class='item-card']当前数量=len(当前元素列表)记录日志:"当前已加载 "+当前数量+" 条"# 检查是否不再增加如果 当前数量==上次数量:连续无变化次数+=1如果 连续无变化次数>=3:# 连续3次没变化,认为加载完成记录日志:"加载完成,共 "+当前数量+" 条"跳出循环 否则:连续无变化次数=0上次数量=当前数量# 防止死循环如果 当前数量>10000:# 超过上限就停记录日志:"达到采集上限"跳出循环# 采集所有已加载的数据采集所有可见数据1.5 "加载更多"按钮
循环:# 检查是否有"加载更多"按钮加载更多按钮存在=检查元素://button[contains(text(),'加载更多')]或//a[text()='查看更多']如果 加载更多按钮存在==False:记录日志:"没有更多数据"跳出循环 点击:加载更多按钮# 等待新数据出现当前项目数=len(获取元素列表(//div[@class='item']))等待JS条件:"document.querySelectorAll('.item').length > "+当前项目数 超时时间:10秒 等待:随机(500,1500)毫秒第二章:反爬虫应对策略
2.1 常见反爬虫检测手段
| 检测方式 | 原理 | 影响 |
|---|---|---|
| User-Agent检测 | 检查请求头 | 拒绝非正常UA |
| 请求频率检测 | 访问太快 | 限速或封IP |
| IP封禁 | 同IP频繁请求 | 直接封锁 |
| Cookie/Session检测 | 缺少正常浏览痕迹 | 返回错误页 |
| JavaScript检测 | 检查浏览器特征 | 验证码或跳转 |
| 验证码 | 人机验证 | 流程中断 |
| 行为分析 | 鼠标移动、停留时间等 | 标记为机器人 |
2.2 基础防护:模拟人类行为
# 1. 随机等待(最重要)访问URL 等待:随机(1500,4000)毫秒# 不要固定时间# 2. 随机鼠标移动鼠标移动到随机位置# 模拟人类阅读习惯# 3. 随机滚动执行JS:""" const scrollAmount = Math.floor(Math.random() * 500) + 200; window.scrollBy(0, scrollAmount); """等待:随机(500,1500)毫秒# 4. 设置真实User-Agent设置浏览器UA:"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36"# 5. 控制采集速度每页采集后等待:随机(2000,5000)毫秒 每10页额外休息:随机(10000,30000)毫秒# 10-30秒2.3 处理IP封禁:代理IP池
代理IP列表=["http://user:pass@proxy1.example.com:8080","http://user:pass@proxy2.example.com:8080","http://user:pass@proxy3.example.com:8080",]当前代理索引=0请求计数=0每个代理最多请求数=50循环:# 检查是否需要切换代理如果 请求计数>=每个代理最多请求数:当前代理索引=(当前代理索引+1)%len(代理IP列表)请求计数=0记录日志:"切换到代理 "+(当前代理索引+1)# 重新初始化浏览器(使用新代理)关闭当前浏览器 新建浏览器:代理:代理IP列表[当前代理索引]等待:3000毫秒# 正常采集逻辑采集一页数据 请求计数+=12.4 检测被封的信号
子流程:CheckIfBlocked# 检查页面标题页面标题=获取页面标题()封锁关键词=["Access Denied","403 Forbidden","Error","验证","安全验证"]遍历 封锁关键词askeyword:如果 keyword 在 页面标题:返回True# 检查页面内容页面内容=获取页面文本()如果"请验证您不是机器人"在 页面内容:返回True如果"您的访问异常"在 页面内容:返回True# 检查目标元素是否存在如果 目标元素不存在(//div[@id='product-list']):返回True返回False# 在主流程中使用访问URL 如果 CheckIfBlocked():记录日志:"检测到IP被封,等待10分钟后重试"等待:600000毫秒# 10分钟切换代理 重新访问URL2.5 Cloudflare绕过技巧
许多网站用了Cloudflare保护,会有一个5秒等待页面:
访问URL 等待:8000毫秒# 等Cloudflare验证完成# 检查是否还在Cloudflare页面如果"Checking your browser"在 获取页面文本():等待:10000毫秒# 再等10秒# 验证是否进入了目标页面如果 目标元素不存在(//div[@id='main-content']):记录日志:"Cloudflare验证未通过"# 尝试刷新刷新页面 等待:10000毫秒第三章:懒加载的特殊处理
3.1 图片懒加载
temu店群自动化报活动案例
懒加载的图片URL通常在data-src而不是src:
<!-- 未加载状态 --><imgsrc="placeholder.gif"data-src="real_image.jpg"class="lazy"><!-- 加载后变成 --><imgsrc="real_image.jpg"class="lazy loaded"># 错误做法:获取src属性(得到placeholder)图片URL=获取属性://img[@class='lazy'],src# 正确做法:先滚动到元素可见位置,再获取滚动到元素://img[@class='lazy']等待:500毫秒# 等待懒加载触发# 优先取src,如果还是placeholder,取data-src图片URL=获取属性://img[@class='lazy loaded'],src 如果 图片URL 包含"placeholder"或 图片URL 为空:图片URL=获取属性://img[@class='lazy'],data-src3.2 内容懒加载(滚动可视区触发)
# 分段滚动,确保所有内容都被触发加载页面高度=执行JS:"return document.body.scrollHeight"每段高度=500当前位置=0循环:执行JS:"window.scrollTo(0, "+当前位置+")"等待:300毫秒# 等待这段内容加载当前位置+=每段高度 如果 当前位置>页面高度:跳出循环# 滚回顶部,开始正式采集执行JS:"window.scrollTo(0, 0)"等待:1000毫秒第四章:采集数据质量保障
4.1 数据验证
子流程:ValidateProductData(product)必填字段=["title","price","url"]遍历 必填字段asfield:如果 field 不在 product 或 product[field]为空:返回False,"缺少字段: "+field# 价格格式验证尝试:price=浮点数(product["price"].替换(",","").替换("¥",""))如果 price<=0或 price>1000000:返回False,"价格异常: "+price 异常:返回False,"价格格式错误"返回True,"OK"4.2 去重处理
已采集URL=集合()遍历 产品URL列表asurl:如果 url 在 已采集URL:记录日志:"跳过重复URL: "+url 继续# 采集详情详情=采集详情页(url)已采集URL.添加(url)保存(详情)总结
| 场景 | 最佳方案 |
|---|---|
| URL参数翻页 | 循环构造URL,范围可知时最高效 |
| 按钮翻页 | 检测"下一页"是否存在+是否禁用 |
| 无限滚动 | 循环滚动到底部,连续无变化则停止 |
| 加载更多按钮 | 点击后等待元素数量增加 |
| 反爬虫 | 随机延迟+随机鼠标+代理IP轮换 |
| 懒加载图片 | 先滚动到可见区域,再获取src |
| 数据质量 | 验证+去重+断点续采 |
这些技巧组合使用,能覆盖95%的数据采集场景。
下一篇推荐:《影刀RPA存储方案对比:Excel、SQLite、MySQL怎么选?》
关注作者获取更多影刀RPA实战教程!