Search code examples
pythonselenium-webdriverscrollwebdriverwebdriverwait

ElementClickInterceptedException: element click intercepted: Element is not clickable clicking on a download link


Using Selenium & Python I need to click on targets.simple.csv download a .csv file from this page: https://www.opensanctions.org/datasets/default/

Here is the code I have written:

import pandas as pd
import numpy as np
from datetime import date
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium import webdriver
import time
from selenium.webdriver.support import expected_conditions
from selenium.webdriver.support import expected_conditions
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait

chromedriver_path = r"./driver/chromedriver"
browser = webdriver.Chrome(executable_path=chromedriver_path)
url = "https://www.opensanctions.org/datasets/default/"
topics_xpath = '/html/body/div[1]/div/div/div[1]/section[2]/table/tbody/tr[6]/td[2]/a/code'
browser.get(url)
browser.maximize_window()
time.sleep(10)  #Wait a little for page to load.
WebDriverWait(browser, 10).until(EC.element_to_be_clickable((By.XPATH, "/html/body/div[1]/div[2]/div/div/div[2]/div/button[1]"))).click()
WebDriverWait(browser, 10).until(EC.element_to_be_clickable((By.XPATH, "/html/body/div[1]/div/div/div[1]/section[2]/table/tbody/tr[6]/td[2]/a/code"))).click()

But I get this error:

ElementClickInterceptedException: element click intercepted: Element is not clickable at point (360, 1282)
  (Session info: chrome=114.0.5735.198)

However, the error does not occur if:

  • I run the script
  • As soon as the page opens, I manually scroll (with the mouse) where the downloadable csv file is.

If I do so, then the code downloads the .csv file.

Is there a way in Python to scroll to the file I want to download without me having to do it manually?


Solution

  • you can refer this codes, the document is https://www.selenium.dev/documentation/webdriver/actions_api/wheel/#scroll-to-element

    perform() can move down one by one, once it find the href, it will break the while loop. so you can use a little step one by one.

    from_viewport() used to locate the first coordinate in the screen.

    kkk_y = int(kkk.rect['y']) can get the element's y coordinate

    below code can scroll to the element.
    ActionChains(driver).scroll_from_origin(scroll_origin, 0, kkk_y).perform()

    I don't install the chrome and driver, so I use the edge.

    from selenium.webdriver.support.ui import WebDriverWait
    from selenium.webdriver.common.by import By
    from selenium.webdriver.support import expected_conditions as EC
    from selenium import webdriver
    import time
    from selenium.webdriver.edge.service import Service
    from selenium.webdriver.common.by import By
    from selenium.webdriver.support.ui import WebDriverWait
    from selenium.webdriver.common.actions.wheel_input import ScrollOrigin
    from selenium.webdriver import ActionChains
    
    driverpath = r"C:\Users\10696\Desktop\access\6\msedgedriver.exe"
    
    service=Service(executable_path=driverpath)
    driver = webdriver.Edge(service = service)
    url = "https://www.opensanctions.org/datasets/default/"
    
    topics_xpath = '/html/body/div[1]/div/div/div[1]/section[2]/table/tbody/tr[6]/td[2]/a/code'
    driver.get(url)
    kk = driver.find_element(By.XPATH, "/html/body/div[1]/div[2]/div/div/div[2]/div/button[1]")
    WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, "/html/body/div[1]/div[2]/div/div/div[2]/div/button[1]")))
    kk.click()
    
    kkk = driver.find_element(By.XPATH, "/html/body/div[1]/div/div/div[1]/section[2]/table/tbody/tr[6]/td[2]/a")
    scroll_origin = ScrollOrigin.from_viewport(0, 0)
    kkk_y = int(kkk.rect['y'])
    ActionChains(driver).scroll_from_origin(scroll_origin, 0, kkk_y).perform()
    WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, "/html/body/div[1]/div/div/div[1]/section[2]/table/tbody/tr[6]/td[2]/a")))
    time.sleep(2)
    kkk.click()
    

    another thing

    you should get the website and use requests to download something, like below not using click, I can download this file normally targets.simple.csv.

    
    from selenium.webdriver.common.by import By
    from selenium import webdriver
    import os
    from selenium.webdriver.edge.service import Service
    from selenium.webdriver.common.by import By
    import requests
    
    driverpath = r"C:\Users\10696\Desktop\access\6\msedgedriver.exe"
    
    service=Service(executable_path=driverpath)
    driver = webdriver.Edge(service = service)
    url = "https://www.opensanctions.org/datasets/default/"
    
    driver.get(url)
    kkk = driver.find_element(By.XPATH, "/html/body/div[1]/div/div/div[1]/section[2]/table/tbody/tr[6]/td[2]/a")
    hrefkkk = kkk.get_attribute("href")
    if hrefkkk:
        con = requests.get(hrefkkk)
        if con.status_code==200:
            with open(os.path.join(r'C:\Users\10696\Desktop\access\6', kkk.text), 'wb') as obj:
                obj.write(con.content)