即使WebElement不是visib,_displayed()方法是否返回true

2021-11-29 21:47:46 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在做一个测试,在某个时刻,它记录了一些显示在可滚动表中的数据:

<div class='table-body'>
   <div class='scroll-wrapper>
      <div class='row'>
         <button class='button' type='button'></button>
         <div class='inner-data></div>
      </div>
      <div class='row'>
         <button class='button' type='button'></button>
         <div class='inner-data></div>
      </div>
      <div class='row'>
         <button class='button' type='button'></button>
         <div class='inner-data></div>
      </div>
   </div>
</div>

屏幕上显示了表格中的行总数,允许我使用while循环,以确保收集所有数据。 但是,正如您在html代码中看到的,每行都有一个按钮,我为每行单击。我的问题是:在某个时刻,我的方法find_elements_by_css_selector(div.row)找到一个在窗口上不可见的WebElement,并尝试单击它的<button>。 因此,我得到以下错误:

ElementNotInteractableException: Message: Element <button class="btn" type="button"> could not be scrolled into view

我尝试使用is_displayed()方法和is_enabled()检查元素在屏幕上是否可见,不幸的是,它们总是返回True。你知道吗

你们有什么解决办法吗?你知道吗

2条回答
网友
1楼 ·

感谢您的回答@DebanjanB。您的解决方案运行良好:

try:
    WebDriverWait(driver, 20).until(EC.visibility_of_element_located((By.CSS-SELECTOR, "button"))):
    element.click()
except TimeoutException:
    # The button is not clickable, I scroll down

但是,我知道按钮只有在DOM中才是不可点击的(而且不可见),但在我的窗口中是不可见的。即使你的解决方案有效,考虑到我在20秒后有一个超时,这也是相当耗时的。我知道我可以减少WebDriverWait(driver, time)解决方案中的时间参数,但我找到了另一个解决方案:

try:
    self.driver.find_element_by_css_selector('button').click() 
except ElementNotInteractableException:
    # The button is not clickable, I scroll down

不管怎样,谢谢你的帮助,我希望这个技巧能帮助别人;)

网友
2楼 ·

此错误消息。。。你知道吗

ElementNotInteractableException: Message: Element <button class="btn type="button"> could not be scrolled into view

…意味着所需的元素无法滚动到视图中,并且不可交互。你知道吗

如果您观察相关的HTML,<button>标记是:

<button class='button' type='button'></button>

它们位于父<div>标记中,如下所示:

<div class='row'>

您已经用定位策略将<div>标记作为目标:

find_elements_by_css_selector(div.row)

但是对于其他元素返回错误ElementNotInteractableException

<button class="btn      type="button">
observe the ^^^class^^^ attribute value

这不是你想要的元素。因此你看到了错误。你知道吗


解决方案

作为针对<button>标记的解决方案,您需要进一步深入挖掘visibility_of_all_elements_located()WebDriverWait,然后单击每个元素,您可以使用以下Locator Strategies

  • 使用CSS_SELECTOR

    for element in WebDriverWait(driver, 20).until(EC.visibility_of_all_elements_located((By.XPATH, "div.table-body > div.scroll-wrapper div.row > button.button[type='button']"))):
        WebDriverWait(driver, 20).until(EC.visibility_of(element)).click()
    
  • 使用XPATH

    for element in WebDriverWait(driver, 30).until(EC.visibility_of_all_elements_located((By.XPATH, "//div[@class='table-body']/div[@class='scroll-wrapper']//div[@class='row']/button[@class='button' and @type='button']"))):
        WebDriverWait(driver, 20).until(EC.visibility_of(element)).click()
    
  • 注意:必须添加以下导入:

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

相关问题