Python Selenium悬停动作在内存中串联

问题描述

我正在测试一个网站,该网站的菜单带有悬停菜单

我创建了一个与此菜单进行交互的功能

def go_to(navbar_item,menu_item):
    # find the navbar item
    assets_main_menu = driver.find_element(By.ID,navbar_item)
    #hover over the navbar item,so the submenu appears
    hover.move_to_element(assets_main_menu).perform()
    # find the submenu item
    xpath = "//*[contains(text(),\'" + menu_item + "\')]"
    destination = driver.find_element_by_xpath(xpath)
    # hover over the submenu item and clicks
    hover.move_to_element(destination).click().perform()

问题是我多次使用此功能,例如:

# action 1
go_to('navbar item1 id','submenu item1')
do_something()
# action 2
go_to('navbar item1 id','submenu item2')
do something()
# action 3
go_to('navbar item1 id','submenu item3')
do_something()

硒实际上重复了前面的菜单项中的步骤,例如:

实际数量 动作1,执行操作->动作1,操作2,执行某事->动作1,操作2,动作3,执行某事

相反,我期望的输出将是:

动作1,做某事->动作2,做某事->动作3,做某事


我尝试取消设置变量:

navbar_item,menu_item,悬停,xpath,目的地。

函数结尾处没有运气。

我还尝试在函数中实例化悬停

hover = ActionChains(driver);

但是在最后一次尝试中,我的代码停止了工作。

解决方法

调用操作链时,perform()不会清除前面的步骤。您只真正共享了功能,所以真正的罪魁祸首是代码的结构以及python如何使用变量。

我注意到在您的函数中,您传入了两个strings,但是您的函数知道driverhover是什么。听起来您正在使用全局变量。

为演示您的问题,我为您创建了一个带有点击计数器的简单页面:

<html>
    <body>
        <button id="button" onclick="document.getElementById('input').value = parseInt(document.getElementById('input').value) + 1">Click me</button>
        <input id="input" value="0"></input>
    </body>
</html>

这是一个平面页面,每次您按下按钮时,它都会弹出一个数字: clicker

然后,为了向您展示发生了什么,我创建了一个类似的代码版本:

driver = webdriver.Chrome()
driver.implicitly_wait(10)
driver.get(r"c:\git\test.html")

actions = ActionChains(driver)

def ClickByActions(element):
    actions.move_to_element(element).click().perform()

#find the button and click it a few times...
button = driver.find_element_by_id('button')
ClickByActions(button)
ClickByActions(button)
ClickByActions(button)

因此,您希望最终点击计数值为3。但是,它是6。 enter image description here

与您的问题相同。第一次通话进行+1,第二次通话进行+1 +1,第三次通话进行+1 +1 +1。

最后!解决方案-使用驱动程序在函数中创建动作链:

def ClickByActions(element):
    localActions = ActionChains(driver)
    localActions.move_to_element(element).click().perform()

end result

我在评论中指出您说您尝试过此操作。你能试试吗?

  • 不使用hover,而是使用另一个名称-
  • 传入驱动程序,而不是依赖于它是全局变量。为此,您将使用go_to(navbar_item,menu_item,driver)
  • 显然hover.reset_actions()也应该起作用-但这对我不起作用。

如果这些方法不起作用,请共享您的站点URL,以便我可以在您的实际站点上尝试或说出错误所在并描述发生的情况。