添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

在 Selenium 中使用 ActionChains 的动作链进行元素操作非常便捷,可以省去很多定位元素的麻烦,但是这里面不小心也会踩坑,尤其是 click 这个函数的使用要稍加小心,否则它会“点击”不到你期望的元素。

来,看案例。

被测页面: https://login.sina.com.cn/signup/signup?entry=homepage

测试需求:

  1. 通过元素定位,点击“新闻”复选框;
  2. 以 ActionChains 方式通过模拟按下键盘的 Tab 键,将焦点切换到“娱乐”复选框;
  3. 通过 click() 函数选中“娱乐”复选框。

代码运行现象描述:

  1. 通过元素定位方式,“新闻”复选框被正确选中 【✔】
  2. 以 ActionChains 方式执行时,“娱乐”复选框没有被选中,而且“新闻”复选框的选中状态被清除 【✘】

代码如下:

from selenium import webdriver
from selenium.webdriver import ActionChains
from selenium.webdriver.common.keys import Keys
# 打开火狐浏览器
driver = webdriver.Firefox()
# 打开新浪注册页面
driver.get('https://login.sina.com.cn/signup/signup?entry=homepage')
# 从浏览器开发者工具中直接复制“新闻”复选框的 CSS 选择器路径
news_css = '.checklst > label:nth-child(1) > input:nth-child(1)'
# 定位到 “新闻” 复选框
ck_news = driver.find_element_by_css_selector(news_css)
# 点击 “新闻” 复选框,获得初始焦点位置
ck_news.click()
# 依次实现动作链: 移动到“新闻” -> 点击 Tab键(到“娱乐”) -> 点击 -> 执行
ActionChains(driver).move_to_element(ck_news).\
    send_keys(Keys.TAB).click().\
    perform()

发现问题了没有,在 ActionChains 的动作链中,click() 函数没有按我们的意愿执行!!

截取 click 函数的部分 源码 看看

位置:\Lib\site-packages\selenium\webdriver\common\action_chains.py

有几点需要注意:

  • 这个函数带有一个默认参数 on_element,默认值为 None;
  • 如果传入了一个页面元素,则点击此页面元素;
  • 如果没有传入指定元素,则点击当前的焦点元素。

上面的代码中,我们没有为 click 函数传参数,也就是说它点击的是当前页面的焦点元素。那么问题来了,当前页面的焦点元素是哪个呢?

再从源码中继续读一下 ActionChains 这个类的说明:

class ActionChains(object):

。。。。。。。。。。

Generate user actions.

When you call methods for actions on the ActionChains object,

the actions are stored in a queue in the ActionChains object.

When you call perform(), the events are fired in the order they

are queued up.

看明白了吧,只有当调用 perform() 这个函数的时候,前面写的一大串动作链才被依次执行。

也就是说:

  • 在 ActionChains 语句之前,焦点位置在 “新闻” 这个复选框上。
  • 在执行 perform() 之前,焦点位置一直在 “新闻” 这个复选框上。
  • 在执行 perform() 之前的 click() 操作,也是在对焦点元素 “新闻” 进行的点击操作,所以非但没有选中 “娱乐”,还把已经选中的 “新闻” 给清除了选中状态。

接下来我们看看如何解决吧。整体思路是将前面的动作链断开,将点击操作独立出来。

改变前错误代码:

ActionChains(driver).move_to_element(ck_news).\
    send_keys(Keys.TAB).click().\
    perform()

改变后代码:

ActionChains(driver).move_to_element(ck_news).\
    send_keys(Keys.TAB).perform()
ActionChains(driver).\
    move_to_element(driver.switch_to.active_element).\
    click().perform()

改变后分析:

  1. 模拟按下 Tab 键后,立即 perform 执行,当前焦点元素位置(新闻)真实发生改变,定位到了下一个元素(娱乐);
  2. 通过 switch_to 操作,重新定位到当前活动(焦点)元素处,即“娱乐”复选框,此时执行“click”点击操作就没有问题了。

附上最终代码:

from selenium import webdriver
from selenium.webdriver import ActionChains
from selenium.webdriver.common.keys import Keys
# 打开火狐浏览器
driver = webdriver.Firefox()
# 打开新浪注册页面
driver.get('https://login.sina.com.cn/signup/signup?entry=homepage')
# 从浏览器开发者工具中直接复制“新闻”复选框的 CSS 选择器路径
news_css = '.checklst > label:nth-child(1) > input:nth-child(1)'
# 定位到 “新闻” 复选框
ck_news = driver.find_element_by_css_selector(news_css)
# 点击 “新闻” 复选框,获得初始焦点位置
ck_news.click()
# 依次实现动作链: 移动到“新闻” -> 点击 Tab键(到“娱乐”) -> 执行
# 作用:实现焦点元素切换
ActionChains(driver).move_to_element(ck_news).\
    send_keys(Keys.TAB).perform()
# 依次实现动作链: 移动到焦点元素(娱乐) -> 点击 -> 执行
# 作用:点击最新的焦点元素
ActionChains(driver).\
    move_to_element(driver.switch_to.active_element).\
    click().perform()
				
selenium中的使用WebElement.click()出现失效是个老大难的问题,在stackoverflow上也有不少人在抱怨,说从3.0到4.1都没有解决。抛开html页面元素相互遮盖和元素定位不准的情况,经过测试,发现主要出现在chrome 和edge浏览器上,同样一个网站,chrome浏览器点击失效但是使用firefox正常。网上的资料提出了不少的解决办法,但是有些是不靠谱的 ,现一一总结如下: 1.WebElement.click()点击成功,但是程序挂起,不能运行下一步。 ...
要实现拖拽印章的动作,我引入ActionChains类模拟鼠标拖动,但却发现没有效果 #通过指定坐标来拖动,没有效果 drag_and_drop_by_offset().perform() #通过source和target指定两个位置拖动,没有效果 drag_and_drop().perform() #然后还试了分步拖动,还是没效果 click_and_hold().perform() move_to_element().perform() release().perform() 元素是可以定位到的
情景:web自动化模拟拖拽元素,从一个位置拖动到另一个画布canvas,使用ActionChains的方法没有实现,后来也换了pywin32库也没有实现最后找到pyautogui库 ,不过调试坐标点还是很麻烦,只能说是解决了问题。听说opencv处理坐标很方便,还没有使用,有兴趣可以试试。下面是当用的代码,直接贴下面: dragged = wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, "#centerControls >
动态加载的元素上click事件不生效 $(".openORclose2").click(function () { if ($(this).hasClass("checkOpen2")) { $(this).removeClass("checkOpen2"); $(this).parent().parent().removeClass("QAhover"); $(this).parent().parent().
1、本文使用Python语言,以淘宝网为例 2、本文将介绍selenium–webdriver库中的ActionChains类,该类提供了模拟鼠标的常用方法,包括单击、双击、悬停、拖动等常用功能 3、前置步骤,需要先安装selenium并导入ActionChains类 一、ActionChains类方法介绍 1.执行所有存储的操作 - perform() perform(self)预学习perform()方法,首先要先了解一下ActionChains执行原理: 当你调用ActionChains中的
1.ActionChains基本用法 首先需要了解ActionChains执行原理,当你调用ActionChains的方法,不会立即执行,而是会将所有的操作按顺序存放在一个队列里,当你调用perform()方法,队列中的间会依次执行。 2、ActionChains方法列表 click_and_hold(on_element=None) ——点击鼠标左键,不松开 context_click(on_element=None) ——点击鼠标右键 double_click(on_element=None).