【问题标题】:Selenium not blocking for element硒不阻塞元素
【发布时间】:2020-12-05 16:24:50
【问题描述】:

我在 Selenium 执行中遇到了不一致的问题。 我在下面粘贴的代码 sn-p 的最后一行执行不一致。有时它可以工作,有时它会抛出一个错误,指出找不到元素。在尝试执行点击之前,Selenium 不会“阻止”元素出现吗?我使用 Selenium IDE 生成了它。我在这里缺少什么?

self.driver.find_element(By.CSS_SELECTOR, ".dx-ellipsis:nth-child(2)").click()
self.driver.switch_to.default_content()
self.driver.find_element(By.CSS_SELECTOR, "#PageContentPlaceHolder_TimeControlSplitter_TimeControlContent_TimesheetEntrySplitter_TimesheetDetailsMenu_DXI0_T > .dxm-contentText").click()

【问题讨论】:

  • 如果元素是JS动态加载的,如果你在加载之前搜索它们,selenium可能找不到元素。
  • 您想到的“阻塞”称为隐式等待。请参阅下面有关显式等待的答案。这是更好的约定。

标签: python selenium selenium-webdriver iframe webdriverwait


【解决方案1】:

如果元素碰巧被 JS 动态加载,并且如果您在加载之前搜索它们,Selenium 可能找不到元素。

您可以尝试隐式等待或显式等待。

隐式等待的情况下,docs 说:

隐式等待告诉 WebDriver 在尝试查找任何不立即可用的元素(或多个元素)时轮询 DOM 一段时间。

你可以这样做:

from selenium import webdriver

driver = webdriver.Chrome()
driver.implicitly_wait(10) #wait and poll for 10 seconds

explicit waiting 意味着明确指定要等待它可用的元素。根据docs

显式等待是您定义的代码,用于等待特定条件发生,然后再继续执行代码。

你可以这样做:

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

driver = webdriver.Firefox()
driver.get("http://somedomain/url_that_delays_loading")

element1 = WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.CSS_SELECTOR, ".dx-ellipsis:nth-child(2)")))
element1.click()

self.driver.switch_to.default_content()

element2 = WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.CSS_SELECTOR, "#PageContentPlaceHolder_TimeControlSplitter_TimeControlContent_TimesheetEntrySplitter_TimesheetDetailsMenu_DXI0_T > .dxm-contentText")))
element2.click()

【讨论】:

    【解决方案2】:

    当您使用代码行时:

    self.driver.switch_to.default_content()
    

    大概您正在将Selenium 的焦点从frameiframe 切换到顶级内容。因此,您需要诱导WebDriverWait 使所需的元素可点击,您可以使用以下Locator Strategy

    self.driver.switch_to.default_content()
    WebDriverWait(self.driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "#PageContentPlaceHolder_TimeControlSplitter_TimeControlContent_TimesheetEntrySplitter_TimesheetDetailsMenu_DXI0_T > .dxm-contentText"))).click()
    

    注意

    from selenium.webdriver.support.ui import WebDriverWait
    from selenium.webdriver.common.by import By
    from selenium.webdriver.support import expected_conditions as EC
    

    参考文献

    您可以在以下位置找到一些相关的详细讨论:

    【讨论】:

    • 如何为每个可点击元素执行此操作?
    【解决方案3】:

    等待元素加载

    from selenium.webdriver.common.by import By
    from selenium.webdriver.support.ui import WebDriverWait
    from selenium.webdriver.support import expected_conditions as EC
    
    
    WebDriverWait(self.driver, 10).until(EC.element_to_be_clickable((By.CSS_SELECTOR, ".dx-ellipsis:nth-child(2)"))).click()
    self.driver.switch_to.default_content()
    WebDriverWait(self.driver, 10).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "#PageContentPlaceHolder_TimeControlSplitter_TimeControlContent_TimesheetEntrySplitter_TimesheetDetailsMenu_DXI0_T > .dxm-contentText"))).click()
    

    数字是驱动程序在继续之前应该花费多长时间寻找元素。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-10-07
      • 2020-12-01
      • 2014-04-13
      • 1970-01-01
      • 2023-03-23
      • 2016-11-28
      • 1970-01-01
      • 2014-05-25
      相关资源
      最近更新 更多