影刀RPA 鼠标操作详解:单击、双击、右键、悬停、拖拽
影刀RPA 鼠标操作详解单击、双击、右键、悬停、拖拽作者林焱鼠标操作是RPA最基础的能力之一。在网页自动化中大部分操作可以用【点击】指令完成。但有些场景下【点击】不管用——需要模拟鼠标悬停展开菜单、右键弹出上下文菜单、双击进入编辑模式、拖拽排序或滑动验证。这些操作需要用【鼠标操作】类指令。这篇文章把影刀中五种鼠标操作的应用场景和实操方法讲全。一、单击Click1.1 基本单击最常用的操作用【点击】指令【点击】 目标元素定位到目标 鼠标按键左键 点击类型单击大部分场景下【点击】就够用了。但有些特殊情况需要注意坑1点击被遮挡目标元素上方有浮层遮挡点击点到了浮层上而不是目标元素。解决方法先关闭浮层或者用JS直接触发点击事件document.querySelector(#target).click();坑2元素可点击区域很小有些元素的可点击区域很小比如一个很小的图标鼠标模拟时稍微偏一点就点歪了。用JS点击可以精确定位document.querySelector(#target).click();1.2 点击坐标有时候你不知道具体要点击哪个元素只知道要点击页面上的某个坐标位置【鼠标点击坐标】 横坐标500 纵坐标300 鼠标按键左键坑坐标是相对于什么的坐标可以是相对于浏览器窗口的也可以是相对于屏幕的。搞清楚你的坐标参考系。一般用相对于浏览器窗口的坐标。坑不同分辨率下坐标不同在1920x1080屏幕上调试好的坐标换到1366x768的屏幕上就偏了。坐标点击方案不通用尽量用元素定位代替坐标点击。二、双击DoubleClick2.1 什么时候需要双击双击表格单元格进入编辑模式双击文件打开双击选中文本某些网站的自定义交互双击放大图片等2.2 操作方法【点击】 目标元素定位到目标 鼠标按键左键 点击类型双击或者用模拟鼠标拼多多店群自动化报活动上架【模拟鼠标】 操作类型双击 目标元素定位到目标坑双击间隔太快或太慢有些双击操作对两次点击的间隔有要求。太慢了系统认为是两次单击太快了可能没触发双击事件。影刀默认的间隔通常没问题如果不行可以尝试在两次点击之间加微小延时。坑双击选中了文字后触发了其他操作双击文本会自动选中文本如果页面上有选中文字后弹出的工具栏可能会干扰后续操作。双击后如果不需要选中状态用【模拟按键】Escape取消。三、右键点击RightClick3.1 什么时候需要右键弹出右键上下文菜单复制、粘贴、另存为等某些网站的自定义右键菜单桌面应用操作3.2 操作方法【点击】 目标元素定位到目标 鼠标按键右键 点击类型单击或者【模拟鼠标】 操作类型右键点击 目标元素定位到目标3.3 右键菜单的操作右键点击后弹出上下文菜单需要继续点击菜单项1. 【点击】右键点击目标元素 2. 【等待元素】等待右键菜单出现 3. 【点击】左键点击菜单中的目标项 4. 坑1右键菜单是系统级菜单定位不到浏览器默认的右键菜单复制、粘贴等是系统级菜单影刀的网页元素定位定位不到。需要用【模拟按键】来操作1. 【点击】右键点击 2. 【模拟按键】CtrlC复制或者用JS禁用默认右键菜单让网站显示自定义菜单document.oncontextmenufunction(){returnfalse;}坑2自定义右键菜单位置不固定自定义右键菜单的弹出位置取决于鼠标右键点击的位置菜单可能出现在不同位置。用菜单项的文本来定位而不是用坐标。四、鼠标悬停Hover4.1 什么时候需要悬停鼠标移到某个元素上展开下拉菜单鼠标悬停显示tooltip提示悬停触发元素状态变化变色、显示操作按钮等模拟用户阅读行为4.2 操作方法【鼠标悬停】 目标元素定位到目标元素 或者用模拟鼠标移动【模拟鼠标】 操作类型移动到元素 目标元素定位到目标4.3 悬停展开菜单后点击最常见的场景悬停展开菜单然后点击菜单项1. 【鼠标悬停】悬停在一级菜单上 2. 【等待元素】等待二级菜单出现 3. 【点击】点击二级菜单项坑1悬停后菜单立即消失鼠标移开一级菜单区域后二级菜单立即消失。如果你先悬停再去定位二级菜单元素鼠标已经移走了菜单也消失了。解决方法悬停后不要移动鼠标直接用元素定位点击二级菜单。影刀的【点击】会自动定位到元素并点击不需要你先把鼠标移过去。坑2悬停效果需要时间有些悬停效果有延迟比如200ms后才展开悬停后立即去找菜单元素可能找不到。加一个短延时1. 【鼠标悬停】悬停 2. 【延时等待】500ms 3. 【等待元素】等待菜单出现坑3悬停在JS模拟的元素上不生效用【执行JavaScript】模拟mouseover事件有些网站的悬停逻辑绑在mouseenter事件上两个事件不一样。两个都触发vartargetdocument.querySelector(#menu);varevent1newMouseEvent(mouseover,{bubbles:true});varevent2newMouseEvent(mouseenter,{bubbles:true});target.dispatchEvent(event1);target.dispatchEvent(event2);五、拖拽Drag Drop5.1 什么时候需要拖拽拖拽排序调整列表项顺序拖拽文件到上传区域滑块验证码看板系统拖拽卡片5.2 操作方法影刀提供专门的拖拽指令【拖拽元素】 源元素要拖动的元素 目标元素拖到的目标位置如果影刀的拖拽指令不好使用模拟鼠标操作1. 【模拟鼠标】移动到源元素 2. 【模拟鼠标】按下左键不释放 3. 【模拟鼠标】移动到目标位置 4. 【模拟鼠标】释放左键5.3 拖拽排序场景拖拽列表项重新排序。1. 【拖拽元素】 源元素要移动的列表项 目标元素目标位置的列表项 坑1拖拽过程中元素位置变了拖拽过程中列表项的位置在动态变化目标元素的坐标可能不对。用JS直接操作DOM顺序更可靠// 将source元素移到target元素前面varsourcedocument.querySelector(#item-3);vartargetdocument.querySelector(#item-1);target.parentNode.insertBefore(source,target);坑2拖拽距离太短没触发有些拖拽组件要求拖拽距离超过一定阈值才触发排序。模拟鼠标移动时确保移动距离足够。5.4 拖拽文件上传TEMU店群矩阵自动化运营核价报活动场景把文件拖到上传区域。这种场景用影刀的拖拽指令不好使因为文件不在网页元素里。更好的方案是直接用input typefile填写路径参考《文件上传与下载的自动化处理》那篇。如果必须模拟拖拽上传用JS构造拖拽事件vardropZonedocument.querySelector(.upload-area);vardtnewDataTransfer();dt.items.add(newFile([],test.pdf,{type:application/pdf}));vareventnewDragEvent(drop,{dataTransfer:dt,bubbles:true});dropZone.dispatchEvent(event);5.5 滑块验证码拖拽场景拖动滑块完成验证。1. 【获取元素位置】获取滑块按钮的位置 2. 【获取元素位置】获取滑块轨道的终点位置 3. 计算需要拖动的距离 4. 【模拟鼠标】移动到滑块按钮 5. 【模拟鼠标】按下左键 6. 循环【模拟鼠标】移动一小步模拟人类拖动轨迹 7. 【模拟鼠标】释放左键坑匀速拖动被识别为机器人匀速直线拖动很容易被验证码系统识别为机器人。需要模拟人类的拖动轨迹——先快后慢、有微小抖动importrandomimportmathdefgenerate_track(distance):生成模拟人类拖动的轨迹track[]current0# 先加速后减速middistance*0.7whilecurrentdistance:ifcurrentmid:# 加速阶段moverandom.randint(2,5)else:# 减速阶段moverandom.randint(1,3)currentmoveifcurrentdistance:currentdistance# 加微小抖动y_jitterrandom.randint(-1,1)track.append((move,y_jitter))# 最后稍微回退一点track.append((-2,0))returntrack六、鼠标操作的最佳实践6.1 优先用元素定位坐标兜底能用元素定位的就不要用坐标。元素定位不受分辨率、窗口大小影响坐标方案换个环境就崩了。6.2 关键操作后加等待每次鼠标操作后给页面时间响应【点击】点击按钮 【等待元素】等待结果出现而不是直接继续下一步6.3 复杂操作用JS替代如果影刀的鼠标指令不好使考虑用JS直接触发事件。JS触发事件更精确、更稳定不受鼠标位置影响。6.4 模拟人类行为在做反爬虫相关操作时加入随机延时和随机偏移模拟人类操作行为每次鼠标操作后【随机延时】200-800ms 点击坐标加随机偏移±3px七、避坑清单坑1鼠标操作在远程桌面断开后失效远程桌面断开后鼠标和键盘模拟可能失效因为没有活动桌面会话。解决方案改用JS触发事件不依赖鼠标模拟。坑2元素在iframe里鼠标操作定位不到iframe内的元素需要先切换到iframe再操作。鼠标坐标也需要考虑iframe的偏移。坑3拖拽后元素引用失效拖拽操作改变了DOM结构之前的元素引用可能失效。拖拽后重新获取元素。坑4右键菜单在无头模式下不显示如果浏览器以无头模式headless运行右键菜单不显示。需要用JS模拟右键菜单的操作。坑5悬停状态不持久【鼠标悬停】只在指令执行期间保持悬停状态下一条指令鼠标可能已经移走了。如果需要持续悬停状态用JS添加CSS类模拟悬停效果document.querySelector(#target).classList.add(hover);