79

I try to scrape this site by Selenium.

I want to click in "Next Page" buttom, for this I do:

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

it works for many pages but not for all, I got this error

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

always for this page

I read this question

and I tried this

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

but I got the same error

Benjamin Loison
  • 3,782
  • 4
  • 16
  • 33
parik
  • 2,313
  • 12
  • 39
  • 67
  • When I go to that page there is no element with the class name, `pagination-r` or `linkAuchan`. I guess the page has changed? – JeffC Jun 30 '16 at 01:57

7 Answers7

199

Another element is covering the element you are trying to click. You could use execute_script() to click on this.

element = driver.find_element_by_class_name('pagination-r')
driver.execute_script("arguments[0].click();", element)
RemcoW
  • 4,196
  • 1
  • 22
  • 37
  • 6
    @RemcoW what is the meaning of `arguments[0]` here? – CKM Apr 30 '18 at 06:02
  • 20
    @chandresh The `execute_script()` method has 2 parameters. The first is the script, the second is a vararg in which you can place any parameters used in the script. In this case we only need the element as parameter, but since it is a vararg our element is the first in the collection. For example you could also do `driver.execute_script("arguments[0].click(); arguments[1].click();" element1, element2)` This would click both elements passed – RemcoW Apr 30 '18 at 10:01
  • 3
    Bear in mind, if you are writing tests that intend to use the website like a real user you are potentially doing something that a real user cannot do because the element they want to click on is covered. Don't do this to just make your tests pass! – Ardesco Mar 13 '19 at 16:31
  • @CKM driver.execute_script("arguments[0].click();", element) - `arguments[0]` is `element`. You can do driver.execute_script("arguments[0].click();doSmthElse(arguments[1])", element, doSmthElseParam) and in this case `arguments[1]` would be `doSmthElseParam` – hipokito Feb 24 '21 at 12:24
28

Because element is not visible on the browser, first you need to scroll down to the element this can be performed by executing javascript.

element = driver.find_element_by_class_name('pagination-r')
driver.execute_script("arguments[0].scrollIntoView();", element)
driver.execute_script("arguments[0].click();", element)
Smart Dev
  • 381
  • 3
  • 2
18

I had a similar issue where using ActionChains was not solving my error: WebDriverException: Message: unknown error: Element is not clickable at point (5 74, 892)

I found a nice solution if you dont want to use 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

or

inputElement.send_keys(Keys.SPACE) #for checkbox etc
Benjamin Loison
  • 3,782
  • 4
  • 16
  • 33
Deepak Garud
  • 977
  • 10
  • 18
2

I have written logic to handle these type of exception .

   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
  • It is more efficient than other available option . Us ElementClickInterceptedException in ignore_exception list . – Chetan Kolhe May 30 '20 at 08:07
  • very good solution! I have added ElementClickInterceptedException and ElementNotInteractableException in the ignore_exception, set timeout to 3 seconds, and works like a charm. – nejcb1 Jun 12 '20 at 06:02
  • I still get the same error after using the above. – Coder Sep 17 '22 at 23:50
1

If you are receiving an element not clickable error, even after using wait on the element, try one of these workarounds:

  • Use Action to move to the location of element and then run perform on action
WebElement element = driver.findElement(By("element_path"));
Actions actions = new Actions(driver);
actions.moveToElement(element).click().perform();`
  • Check for an overlay or spinner on the element and wait for its invisibility
By spinnerimg = By.id("spinner ID");
WebDriverWait wait = new WebDriverWait(driver, timeOutInSeconds);
wait.until(ExpectedConditions.invisibilityOfElementLocated(spinnerimg ));

Hope this helps

Z4-tier
  • 7,287
  • 3
  • 26
  • 42
quickauto
  • 11
  • 2
  • you can use markdown to format the code in your answer, which enhances readability. For example: `WebElement element = driver.findElement(By("element_path")); ` Just wrap the code with the backtick character: ` – Paul Degnan Feb 27 '20 at 03:00
0

Use explicit wait instead of implicit.

new WebDriverWait(TestingSession.Browser.WebDriver, TimeSpan.FromSeconds(10)).Until(ExpectedConditions.ElementExists((By.ClassName("pagination-r'")))); 
Benjamin Loison
  • 3,782
  • 4
  • 16
  • 33
Rakesh Raut
  • 183
  • 3
  • 12
0

I had the similar issue with Chrome driver, changing the PageLoadStrategy of chromeOptions from 'Eager' to Normal fixed my problem.

chromeOptions.PageLoadStrategy = PageLoadStrategy.Normal;