Selenium无法单击元素,因为其他元素将其遮挡

yqkkidmi  于 2022-11-24  发布在  其他
关注(0)|答案(4)|浏览(208)

设置

我使用Python3.x和Selenium填写查询字段,然后单击搜索按钮,

# element containing the product search bar and buttons
search_area = el_id('Products').find_element_by_class_name('searchArea')

# insert name of file to be duplicated
name_field = search_area.find_element_by_xpath("//input[@type='text']")
name_field.clear()
name_field.send_keys('to_be_duplicated')  

# click search button
search_area.find_element_by_xpath('span/a[1]').click()

其中el_id(x) = browser.find_element_by_id(x)

问题

执行上面的代码会出现以下错误,

ElementClickInterceptedException: Element <a class="button button-fleft searchButton" href="#"> is not clickable at point (577.6166763305664,225.06666564941406) because another element <div class="blockUI blockOverlay"> obscures it

我可以通过在抓取并单击按钮之前插入一个硬等待来解决这个错误,

# click search button
time.sleep(1)
search_area.find_element_by_xpath('span/a[1]').click()

但是我用不同的方法来解决这个问题,所以我按照this answer,做了以下操作,

# click search button
search_button = search_area.find_element_by_xpath('span/a[1]')
WebDriverWait(driver, 10).until_not(EC.visibility_of_element_located((By.XPATH, 
"//*[@id="Products"]/tbody/tr[1]/td/div/input")))
search_button.click()

但我得到了完全相同的错误。
我也尝试了this answer,但同样的错误。
我该如何解决这个问题?

lskq00tm

lskq00tm1#

有几种方法可以做到这一点,其中一种方法是通过Javascript执行器。
你可以说:

element = driver.find_element_by_xpath("//div[@class='blockUI blockOverlay']")

driver.execute_script("arguments[0].style.visibility='hidden'", element)

这样,你就可以用class = 'blockUI blockOverlay'来阻止div,如果我是正确的,你的元素就可以被点击了。

ovfsdjhp

ovfsdjhp2#

DebanjanB's answer的nr.5之后,我通过暗示代码在尝试单击之前等待临时覆盖消失来解决这个问题,

wait.until(EC.invisibility_of_element_located((By.XPATH,
              "//div[@class='blockUI blockOverlay']")))
el_xp("//input[@value='Save']").click()
3lxsmp7m

3lxsmp7m3#

此外,您可以尝试按JavaScript单击元素,如下所示:

# element containing the product search bar and buttons
search_area = el_id('Products').find_element_by_class_name('searchArea')

# click element by executing javascript
driver.execute_script("arguments[0].click();", search_area)
oogrdqng

oogrdqng4#

接受的答案要求你知道哪个元素将被用作覆盖。如果这个要求不成立(如@Blaszard在接受的答案下的注解中所提到的),那么你可以使用这个通用函数来获取显示在另一个元素之上的任何元素:

def getOverlappingElement(driver: WebDriver, element: WebElement) -> Optional[WebElement]:
  rect = element.rect
  result = driver.execute_script("return document.elementFromPoint(arguments[0], arguments[1]);",
                                 rect['x'] + rect['width'] // 2, rect['y'] + rect['height'] // 2)
  if result == element:
    result = None
  return result

当您调用getOverlappingElement(driver, button)这样的函数时,它将返回显示在button上方的元素,或者当button不重叠时,它将返回None。
此方法不包括元素部分重叠的情况。对于大多数情况,当加载动画或广告使整个页面重叠时,此方法有效。

相关问题