【问题标题】:Selenium-Debugging: Element is not clickable at point (X,Y)Selenium 调试:元素在点 (X,Y) 处不可点击
【发布时间】:2016-10-19 03:22:39
【问题描述】:

我尝试用 Selenium 抓取这个 site

我想点击“下一页”按钮,为此我这样做:

 driver.find_element_by_class_name('pagination-r').click()

它适用于许多页面,但不适用于所有页面,我收到此错误

WebDriverException: Message: Element is not clickable at point (918, 13). Other element would receive the click: <div class="linkAuchan"></div>

总是为this page

我读过this question

我试过了

driver.implicitly_wait(10)
el = driver.find_element_by_class_name('pagination-r')
action = webdriver.common.action_chains.ActionChains(driver)
action.move_to_element_with_offset(el, 918, 13)
action.click()
action.perform()

但我遇到了同样的错误

【问题讨论】:

  • 当我转到该页面时,没有类名称为pagination-rlinkAuchan 的元素。我猜页面已经改变了?

标签: python selenium selenium-webdriver web-scraping selenium-firefoxdriver


【解决方案1】:

另一个元素覆盖了您尝试点击的元素。你可以使用execute_script()来点击这个。

element = driver.find_element_by_class_name('pagination-r')
driver.execute_script("arguments[0].click();", element)

【讨论】:

  • @RemcoW 这里的arguments[0] 是什么意思?
  • @chandresh execute_script() 方法有 2 个参数。第一个是脚本,第二个是可变参数,您可以在其中放置脚本中使用的任何参数。在这种情况下,我们只需要元素作为参数,但由于它是可变参数,我们的元素是集合中的第一个。例如,您也可以这样做 driver.execute_script("arguments[0].click(); arguments[1].click();" element1, element2) 这将同时点击两个传递的元素
  • 请记住,如果您正在编写旨在像真实用户一样使用网站的测试,那么您可能会做一些真实用户无法做到的事情,因为他们想要点击的元素被覆盖了。不要这样做只是为了让您的测试通过!
  • @CKM driver.execute_script("arguments[0].click();", element) - arguments[0]element。您可以执行 driver.execute_script("arguments[0].click();doSmthElse(arguments[1])", element, doSmthElseParam) ,在这种情况下 arguments[1] 将是 doSmthElseParam
【解决方案2】:

使用显式等待而不是隐式等待。

 new WebDriverWait(TestingSession.Browser.WebDriver, TimeSpan.FromSeconds(10)).Until(ExpectedConditions.ElementExists((By.ClassName("pagination-r'")))); 

【讨论】:

  • 你能用python重写吗
  • 对不起,伙计。我从来没有用过 python,虽然你可以在 python 中获得显式等待的帮助。
  • ExpectedConditions.ElementExists 在这种情况下不会有帮助。元素已找到但不可点击
【解决方案3】:

我遇到了类似的问题,即使用 ActionChains 无法解决我的错误: WebDriverException:消息:未知错误:元素在点不可点击(5 74, 892)

如果您不想使用 execute_script,我找到了一个不错的解决方案:

    from selenium.webdriver.common.keys import Keys #need to send keystrokes

    inputElement = self.driver.find_element_by_name('checkout')

    inputElement.send_keys("\n") #send enter for links, buttons

    inputElement.send_keys(Keys.SPACE) #for checkbox etc

【讨论】:

  • 发送密钥后我们也可以点击吗??
  • @AbhishekGupta - 我们可以使用击键来模拟链接点击或按钮点击等动作。 - 而不是使用鼠标。您需要两者的场景是什么?
  • 在我的情况下,其他一切都不起作用(复选框)。发送 Keys.SPACE 就像魔术一样。
【解决方案4】:

如果您收到 element not clickable 错误,即使在对元素使用 wait 之后,请尝试以下解决方法之一:

  • 使用Action移动到element的位置,然后在action上运行perform
WebElement element = driver.findElement(By("element_path"));
Actions actions = new Actions(driver);
actions.moveToElement(element).click().perform();`
  • 检查 elementwait 上的覆盖层或微调器是否不可见
By spinnerimg = By.id("spinner ID");
WebDriverWait wait = new WebDriverWait(driver, timeOutInSeconds);
wait.until(ExpectedConditions.invisibilityOfElementLocated(spinnerimg ));

希望对你有帮助

【讨论】:

  • 您可以使用 markdown 来格式化您的答案中的代码,从而增强可读性。例如:WebElement element = driver.findElement(By("element_path")); 只需将代码用反引号字符换行即可:`
【解决方案5】:

我已经编写了处理这些异常类型的逻辑。

   def find_element_click(self, by, expression, search_window=None, timeout=32, ignore_exception=None,
                       poll_frequency=4):
    """It find the element and click then  handle all type of exception during click

    :param poll_frequency:
    :param by:
    :param expression:
    :param timeout:
    :param ignore_exception:list It is a list of exception which is need to ignore.
    :return:
    """
    if ignore_exception is None:
        ignore_exception = []

    ignore_exception.append(NoSuchElementException)
    if search_window is None:
        search_window = self.driver

    end_time = time.time() + timeout
    while True:
        try:
            web_element = search_window.find_element(by=by, value=expression)
            web_element.click()
            return True
        except tuple(ignore_exception) as e:
            self.logger.debug(str(e))
            if time.time() > end_time:
                self.logger.exception(e)
                time.sleep(poll_frequency)
                break
        except Exception as e:
            raise
    return False

【讨论】:

  • 它比其他可用选项更有效。我们在 ignore_exception 列表中的 ElementClickInterceptedException 。
  • 非常好的解决方案!我在 ignore_exception 中添加了 ElementClickInterceptedException 和 ElementNotInteractableException,将超时设置为 3 秒,效果非常棒。
【解决方案6】:

由于元素在浏览器上不可见,首先需要向下滚动到该元素 这可以通过执行javascript来执行。

element = driver.find_element_by_class_name('pagination-r')
driver.execute_script("arguments[0].scrollIntoView();", element)
driver.execute_script("arguments[0].click();", element)

【讨论】:

  • arguments[0].scrollIntoView(); 在当前接受的答案中至关重要。这非常有效。
猜你喜欢
  • 1970-01-01
  • 2016-08-22
  • 2016-10-02
  • 2023-03-19
  • 2017-12-08
相关资源
最近更新 更多