collarblind
collarblind

Reputation: 4739

Able to locate element but cannot click on it

I am trying to click on a button that downloads a csv file. I am able to find it but I cannot click on it.

url = "http://www.basketball-reference.com/players/a/acyqu01/gamelog/2015/"
driver = webdriver.Firefox()
driver.get(url)
elem = driver.find_element_by_xpath(".//*[@id='advanced_div']/div[2]/div/span[6]")
elem.click()

ElementNotVisibleException: Message: Element is not currently visible and so may not be interacted with

I've also tried this:

action_chain = webdriver.ActionChains(self.driver)
action_chain.click(elem)
action_chain.perform()

I've noticed the source code has a transparent font. Does that mean it is hidden? I read something about executing a java script to click on it. But, I have no idea how to do that.

Upvotes: 2

Views: 2697

Answers (3)

JeffC
JeffC

Reputation: 25714

The problem is that the DIV that has id=advanced_div is hidden. You can see the HTML for that tag below, note the display:none style.

<div id="advanced_div" style="display: none;">

While looking at the page I noticed that there is a "Switch to Advanced Game Log" link on the page and I clicked it. When I did that, that DIV became visible which meant that the CSV link that you want is now visible.

So to do this with code, you will want to click the same link and then click the CSV link you want. You can use the XPath you have in your code ... or... you can use find_element_by_link_text() which I think makes this task easier. The code below should work.

url = "http://www.basketball-reference.com/players/a/acyqu01/gamelog/2015/"
driver = webdriver.Firefox()
driver.get(url)
driver.find_element_by_link_text("Switch to Advanced Game Log").click()
driver.find_element_by_link_text("CSV").click()

My only concern is that the CSV link text might not be unique. If that's the case, you can use your XPath as below.

driver.find_element_by_link_text("Switch to Advanced Game Log").click()
driver.find_element_by_xpath(".//*[@id='advanced_div']/div[2]/div/span[6]").click()

In general, what you want to do when you write automation is to figure out what the user needs to do on the page and then write code that does the same thing. So, when you come across some element that is hidden, as in this case, figure out how the user would make it visible and then do that with code.

Upvotes: 1

Learner
Learner

Reputation: 5302

Try to implement wait whereas dom loads-below is the full working code for me. It automatically sets firefox profile an avoids csv file save prompt and saves csv into a defined folder, in this case that folder is the Desktop\downloads

import time
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait # available since 2.4.0
from selenium.webdriver.support import expected_conditions as EC # available since 2.26.0
from selenium.webdriver.common.by import By


profile = webdriver.FirefoxProfile()
profile.set_preference("browser.download.folderList", 2)
profile.set_preference("browser.download.manager.showWhenStarting", False)
profile.set_preference("browser.download.dir", r"C:\Users\USER_NAME\Desktop\downloads")
profile.set_preference("browser.helperApps.neverAsk.saveToDisk", "text/csv")


url = "http://www.basketball-reference.com/players/a/acyqu01/gamelog/2015/"

driver = webdriver.Firefox(firefox_profile=profile)
driver.get(url)
WebDriverWait(driver,1000).until(EC.presence_of_all_elements_located((By.XPATH,"//*[@id='basic_div']")))
elem = driver.find_element_by_xpath("//*[@id='basic_div']/div[2]/div/span[6]")
elem.click()
time.sleep(2)
driver.quit()

Upvotes: 0

collarblind
collarblind

Reputation: 4739

This does it

elem = driver.find_element_by_xpath(".//*[@id='basic_div']/div[2]/div/span[6]")
driver.execute_script('arguments[0].click();',elem)

Upvotes: 0

Related Questions