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

Python Selenium hover action concatenates in memory

我正在测试一个网站,该网站有一个菜单,悬停时会显示子菜单。

我创建了一个与此菜单交互的函数:

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()

selenium 实际上会重复之前的步骤来遍历过去的菜单项,例如:

实际提升 动作 1,做某事 -> 动作 1,动作 2,做某事 -> 动作 1,动作 2,动作 3,做某事

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

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


我尝试取消设置变量:

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

在函数末尾,运气不好。

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

hover = ActionChains(驱动程序);

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

调用动作链时,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>

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

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

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)

有了这个,你期望结束 click-count-value 是 3。然而,它是 6。

和你的问题一样。第一次调用 +1,第二次调用 +1 +1,第三次调用 +1 +1 +1。

终于!解决方案 - 使用您的驱动程序在函数中创建动作链:

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

我在评论中注意到你说你试过了。你能试试吗:

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

如果这些都不起作用,请分享您的网站 URL 以便我可以在您的实际网站上尝试,或者说出错误是什么并描述发生了什么。