流程跑着跑着突然崩了,弹出一个红色报错框——这是新手最怕的事。
其实大部分崩溃都可以提前兜住,让流程继续跑,而不是直接死掉。
影刀提供了try-catch-finally机制,专门用来“试一下,不行就换个方式处理,最后无论如何都收个尾”。
我用了半年才完全搞懂三个块的关系,这里把踩过的坑一次说清。
一、try-catch-finally 三块各司其职
| 块 | 作用 | 是否必须 | 什么情况执行 |
|---|---|---|---|
| Try | 放可能出错的指令 | 必须 | 正常执行 |
| Catch | 出错后执行的补救代码 | 可选 | Try里任何指令报错时 | | Finally | 无论对错都执行的收尾代码 | 可选 | Try或Catch执行完后 |
语法结构(影刀中是拖拽三个指令块):
Try
# 可能报错的指令,比如点击一个可能不存在的按钮
Catch
# 出错后记录日志、换另一种方式操作
Finally
# 关闭弹窗、清理缓存等(不管成不成功都要做)
二、Try块:只放“可能失败”的指令
常见适合放Try的指令
- 点击元素(元素可能不存在)
- 获取元素文本(元素可能加载慢)
- 打开网页(网络可能超时)
- 模拟输入(输入框可能被禁用)
不适合放Try的指令
- 变量赋值(
变量 = 1不会失败) - 输出日志(不会失败)
- 循环控制(跳出循环等)
原则: 只有可能产生异常的指令才放Try。放太多无关指令会让Catch块难以定位真正的问题。
实操:捕获一个可能不存在的弹窗关闭按钮
Try
判断元素是否存在(关闭弹窗按钮, 弹窗存在)

如果 弹窗存在 == True
鼠标点击(关闭弹窗按钮)
Catch
输出日志("没有弹窗或关闭失败,继续")
注意:如果把“输出日志”也放Try里,它永远不会报错,但会浪费Catch的判断。
三、Catch块:出错后的“B计划”
当Try块里任何一条指令报错,程序会立刻跳转到Catch块,Try块剩余的指令不再执行。
Catch块应该做的事
- 记录错误信息(用“输出日志”或“获取上一个错误信息”指令)
- 执行备用方案(比如换成另一种点击方式)
- 决定是否继续(用“继续”或“跳出循环”)
获取报错详情
影刀有专门指令“获取上一个错误信息”,放在Catch块里可以拿到报错文本。
Catch
错误信息 = 获取上一个错误信息()
输出日志("出错了:" + 错误信息)
# 比如输出:"出错了:元素'登录按钮'不存在"
实战:点击失败后换模拟点击
Try
鼠标点击(登录按钮, 点击方式=前端点击)
Catch
输出日志("前端点击失败,换模拟点击")
鼠标点击(登录按钮, 点击方式=模拟点击)
容易踩的坑
- Catch块里又放了一个可能出错的指令(比如再点一个不确定的按钮)→ 如果再次报错,没有第二个Catch兜底,流程还是会崩。解决:Catch里尽量用稳定的指令,或者嵌套Try-Catch。
四、Finally块:无论如何都要做的事
Finally块在Try和Catch执行完毕后一定会执行,不管有没有报错。
典型场景
- 关闭弹窗(不管操作成功与否,弹窗都得关)
- 清理缓存、关闭多余的标签页
- 恢复某些状态(比如把滚动条拉回顶部)
示例:翻页采集时确保翻页动作完成
Try
点击下一页按钮
等待元素出现(商品卡片, 5秒)
Catch
输出日志("翻页失败,可能已到最后一页")
设置变量(是否还有下一页, False)
Finally
# 无论翻页成功还是失败,都关闭可能出现的“网络错误”弹窗
如果 判断元素是否存在(网络错误弹窗关闭按钮)
鼠标点击(关闭按钮)
注意: Finally块里如果也报错,流程还是会崩。所以Finally里只放非常稳定的操作。
五、三种组合方式与选择
| 组合 | 结构 | 适用场景 |
|---|---|---|
| Try-Catch | 没有Finally | 只需要记录错误或换方案,不需要收尾 |
| Try-Finally | 没有Catch | 不处理错误,但必须收尾(不常用) |
| Try-Catch-Finally | 完整结构 | 既要处理错误,又要收尾(推荐) |
我90%的场景用Try-Catch(无Finally),因为大多数情况不需要专门收尾。
只有操作涉及“打开新页面”、“修改页面样式”等需要恢复状态时,才加Finally。
六、常见误区(必看)
误区1:把整个流程包在一个大Try里
❌ 错误做法:
Try
打开网页()
登录()
采集数据()
翻页()
# 100行指令
Catch
输出日志("出错了")
这样一旦任何地方出错,你只知道“出错了”,不知道是登录还是翻页出的错。
✅ 正确做法:细化Try块,每个独立操作单独包Try-Catch。
Try 登录
Catch(登录失败处理)
Try 采集第一页
Catch(本页失败,跳过)
误区2:在Catch里用了“跳出循环”但没判断
循环遍历列表(商品列表)
Try
采集商品()
Catch
跳出循环 # 一个商品失败就整个循环停了
这样不合理。应该只跳过当前商品,用“继续”而不是“跳出循环”。
Catch
输出日志("当前商品采集失败,跳过")
继续 # 继续下一个商品
误区3:Finally块里操作依赖Try的成功结果
Try
打开新标签页(URL)
新页面对象 = 获取当前页面对象()
Catch
输出日志("打开失败")
Finally
关闭页面(新页面对象) # 如果Try失败,新页面对象是空,关闭报错
Finally里要用变量前,先判断是否存在。
误区4:认为Catch能捕获所有类型的错误
Catch只能捕获影刀指令执行时报的错(比如元素不存在、超时)。
捕获不了: Python代码指令里的语法错误、JavaScript执行报错。
这些需要在Python代码内部自己用try-except处理。
七、实战:完整异常处理模板
场景:批量采集商品,遇到单个失败要跳过并记录
# 主循环
循环遍历列表(商品URL列表, 当前URL)
调用子流程(采集单个商品,
输入={URL: 当前URL},
输出={成功标志: 是否成功, 商品数据: 数据})
如果 是否成功 == False
写入日志表(当前URL + "采集失败")
继续 # 跳过这个,处理下一个
否则
写入Excel(数据)
子流程 采集单个商品 内部:
Try
打开网页({{URL}})
等待元素出现(标题元素, 10秒, 超时)
如果 超时 == True
抛出异常("页面加载超时") # 手动抛错,让Catch捕获
标题 = 获取元素文本(标题元素)
价格 = 获取元素文本(价格元素)
设置输出参数(成功标志, True)
设置输出参数(商品数据, [标题, 价格])
Catch
错误信息 = 获取上一个错误信息()
输出日志("采集失败:" + 错误信息)
设置输出参数(成功标志, False)
设置输出参数(商品数据, [])
Finally
# 关闭当前标签页,回到商品列表页
关闭当前标签页()
常见问题速查
| 问题 | 原因 | 解决方法 |
|---|---|---|
| Try块报错了但Catch没执行 | Catch块没有正确拖拽到Try下方(断了关联) | 删除重拖,确保Catch有缩进依附于Try |
| 错误信息总是空的 | 没有用“获取上一个错误信息”指令 | 在Catch块里第一行加这个指令 |
| Finally块执行了但顺序不对 | Finally放在了Catch里面 | Finally应该和Catch并列,不缩进 |
| 嵌套Try-Catch导致混乱 | 层次太深 | 尽量拆成子流程,每个子流程有自己的异常处理 |
| 手动想抛出异常(主动报错) | 条件满足时想停止流程 | 用“抛出异常”指令,可以自定义错误文本 |
推荐资源
- 影刀官方学院: “流程控制——异常处理”(视频里演示了try-catch-finally的完整执行顺序)
- 我的文章联动:
- 上一篇:[流程参数实战(选题池14号)]
- 下一篇预告:[影刀RPA完全指南:翻页逻辑的3种实现方式——按钮判断/URL拼接/滚动加载](选题池16号)
- 小技巧: 开发阶段先不加Try-Catch,让流程自然报错,把容易错的点都找出来,再针对性地加异常处理
作者:林焱
本文为《影刀RPA学习手册》系列文章之一,内容源于实操经验的整理与分享。
