I am working on a selenium script in Python, where I am on this stage trying to locate a game icon.
But I can't locate it and click.
enter image description here
This is what I've tried:
self.driver.find_element_by_xpath('/html/body/div[5]/ul/li[17]/a/img')
self.driver.find_element_by_xpath("//*[#id="jackpot_01001"]")
self.driver.find_element_by_xpath('//*[#id="gameList_SLOT_01001"]')
self.driver.find_element_by_id("jackpot_01001").click()
But it will show:
Message: no such element: Unable to locate element: {"method":"xpath","selector":"/html/body/div[5]/ul/li[17]/a/img"}
(Session info: chrome=93.0.4577.82)
This error
Message: no such element: Unable to locate element: {"method":"xpath","selector":"/html/body/div[5]/ul/li[17]/a/img"} (Session info: chrome=93.0.4577.82)
implies that Either one of the following :
Element locator is not correct.
Element is in iframe.
Element is in shadow root.
I am not sure if //li[#id='gameList_SLOT_01001'] or /html/body/div[5]/ul/li[17]/a/img is unique or not. You need to check in HTML DOM.
PS : Please check in the dev tools (Google chrome) if we have unique entry in HTML DOM or not.
Steps to check:
Press F12 in Chrome -> go to element section -> do a CTRL + F -> then paste the xpath and see, if your desired element is getting highlighted with 1/1 matching node.
If it happens to be a unique node, then put some waits and then perform the click.
Update 1:
There are 4 ways to click in Selenium.
I will use this xpath
//li[#id='gameList_SLOT_01001']/descendant::img
Code trial 1:
time.sleep(5)
self.driver.find_element_by_xpath("//li[#id='gameList_SLOT_01001']/descendant::img").click()
Code trial 2:
WebDriverWait(self.driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//li[#id='gameList_SLOT_01001']/descendant::img"))).click()
Code trial 3 :
time.sleep(5)
button = self.driver.find_element_by_xpath("//li[#id='gameList_SLOT_01001']/descendant::img")
self.driver.execute_script("arguments[0].click();", button)
Code trial 4 :
time.sleep(5)
button = self.driver.find_element_by_xpath("//li[#id='gameList_SLOT_01001']/descendant::img")
ActionChains(self.driver).move_to_element(button).click().perform()
Imports :
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.webdriver.common.action_chains import ActionChains
Update 2 :
Since it's a new tab, you would have to switch to it first before interacting with any web element on this new tab.
self.driver.find_element_by_id('RTGWEB-RTGWEB').click()
time.sleep(5)
self.driver.switch_to.window(driver.window_handles[1])
time.sleep(5)
self.driver.find_element_by_xpath("//li[#id='gameList_SLOT_01001']/descendant::img").click()
Related
I am trying to automate the process of liking pages on Facebook. I've got a list of each page's link and I want to open and like them one by one.
I think the Like button doesn't have any id or name, but it is in a span class.
<span class="x1lliihq x6ikm8r x10wlt62 x1n2onr6 xlyipyv xuxw1ft">Like</span>
I used this code to find and click on the "Like" button.
def likePages(links, driver):
for link in links:
driver.get(link)
time.sleep(3)
driver.find_element(By.LINK_TEXT, 'Like').click()
And I get the following error when I run the function:
selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element
The classname attribute values like x1lliihq, x6ikm8r, etc, are dynamically generated and is bound to chage sooner/later. They may change next time you access the application afresh or even while next application startup. So can't be used in locators.
Moreover the the element is a <span> tag so you can't use By.LINK_TEXT
Solution
To click on the element Like you need to induce WebDriverWait for the element_to_be_clickable() and you can use either of the following locator strategies:
Using XPATH and text():
WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, "//span[text()='Like']"))).click()
Using XPATH and contains():
WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, "//*[contains(., 'Like')]"))).click()
Note: You have to add the following imports :
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
References
You can find a couple of relevant detailed discussions on NoSuchElementException in:
selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element while trying to click Next button with selenium
selenium in python : NoSuchElementException: Message: no such element: Unable to locate element
You cannot use Link_Text locator as Like is not a hyperlink. Use XPath instead, see below:
XPath : //span[contains(text(),"Like")]
driver.find_element(By.XPATH, '//span[contains(text(),"Like")]').click()
I have a script that uses Selenium (Python).
I tried to make the code click a button that it acknowledges is clickable, but throws an error stating it;s not clickable.
Same thing happens again in a dropdown menu, but this time I'm not clicking, but selecting an option by value.
from selenium import webdriver
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.common.by import By
from selenium.webdriver.support.select import *
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
# Getting to Chrome and website
website = 'https://www.padron.gob.ar/publica/'
driver = webdriver.Chrome(ChromeDriverManager().install())
driver.get(website)
driver.maximize_window()
#"BUENOS AIRES" in "Distrito Electoral"
distritoElectoralOptions = driver.find_element(By.NAME, 'site')
Select(distritoElectoralOptions).select_by_value('02 ')
#Clicking "Consulta por Zona
WebDriverWait(driver, 35).until(EC.element_to_be_clickable((By.ID, 'lired')))
consultaPorZona = driver.find_element(By.ID, 'lired')
consultaPorZona.click()
#"SEC_8" in "Sección General Electoral"
WebDriverWait(driver, 35).until(EC.visibility_of((By.NAME, 'secg')))
seccionGeneralElectoral = driver.find_element(By.NAME, 'secg')
Select(seccionGeneralElectoral).select_by_value('00008')
I'm getting this error on line 21:
selenium.common.exceptions.ElementNotInteractableException: Message: element not interactable: element has zero size
It works in a ipython notebook if each section is separated, but only if the option "Run all" is not used. Instead, the kernel has to be run on it's own.
I'm using VS Code.
Also, when it reaches the last line, when run in ipynb format, it throws this error:
Message: Cannot locate option with value: 00008
Thank you in advance.
When a web element is present in the HTML-DOM but it is not in the state that can be interacted. Other words, when the element is found but we can’t interact with it, it throws ElementNotInteractableException.
The element not interactable exception may occur due to various reasons.
Element is not visible
Element is present off-screen (After scrolling down it will display)
Element is present behind any other element
Element is disabled
If the element is not visible then wait until element is visible. For this we will use wait command in selenium
wait = WebDriverWait(driver, 10)
element = wait.until(EC.element_to_be_clickable((By.ID, 'someid')))
element.click()
If the element is off-screen then we need to scroll down the browser and interact with the element.
Use the execute_script() interface that helps to execute JavaScript methods through Selenium Webdriver.
browser = webdriver.Firefox()
browser.get("https://en.wikipedia.org")
browser.execute_script("window.scrollTo(0,1000)") //scroll 1000 pixel vertical
Reference this solution in to the regarding problem.
Anybody has a solution to locate a button in webpage with an overlayed popup window like in the following example:
from selenium import webdriver
driver = webdriver.Firefox(executable_path=r'./geckodriver')
driver.get("https://www.academics.de/")
#after waiting for a while the popup window comes up
driver.find_elements_by_xpath("//*[contains(text(), 'Zustimmen')]")
The returned list is empty. Running the following
driver.find_element_by_css_selector(".button-accept")
results in:
NoSuchElementException: Message: Unable to locate element: .button-accept
The element with the text as E-Mail Login is within an iframe so you have to:
Induce WebDriverWait for the desired frame to be available and switch to it.
Induce WebDriverWait for the desired element to be clickable.
You can use either of the following Locator Strategies:
Using CSS_SELECTOR:
driver.get("https://www.academics.de/")
WebDriverWait(driver, 20).until(EC.frame_to_be_available_and_switch_to_it((By.CSS_SELECTOR,"iframe[title='SP Consent Message']")))
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "button[title='Zustimmen']"))).click()
Using XPATH:
driver.get("https://www.academics.de/")
WebDriverWait(driver, 20).until(EC.frame_to_be_available_and_switch_to_it((By.XPATH,"//iframe[#title='SP Consent Message']")))
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//button[#title='Zustimmen']"))).click()
Note : You have to add the following imports :
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
Reference
You can find a couple of relevant discussions in:
Switch to an iframe through Selenium and python
selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element while trying to click Next button with selenium
selenium in python : NoSuchElementException: Message: no such element: Unable to locate element
An easy workaround to your problem would be to use uBlock Origin extension + Fanboy's Annoyances blocklist on your Selenium instance so that these annoying cookies messages would outright never appear. A way of enabling extensions is described in this StackOverflow answer:
Create a new firefox profile via right click windows start button >
run > firefox.exe -P
Then add whatever extensions you want, ublock, adblock plus etc
Call your profile folder with
profile = selenium.webdriver.FirefoxProfile("C:/test")
browser = selenium.webdriver.Firefox(firefox_profile=profile, options=ops)
This is the HTML of the page:
<td class="titulo_lateral" onclick="javascript: abreMenu("layer8");" style="cursor:pointer;">RELATÓRIOS</td>
I'm trying this:
driver.find_element_by_xpath("//*[#id='f']/table/tbody/tr/td/table[2]/tbody/tr/td")
Are you sure that the td, and thus the corresponding XPath, has been rendered on the page when that line of Selenium has executed?
If so, you can try using the full XPath rather than the relative XPath Copy Full XPath button pictured here
You can try with below xpath.
//td[#class='titulo_lateral']
or
//td[text()='RELATÓRIOS' and contains(#onclick,'abreMenu')]
but first you will have to make sure that if it is unique in HTMLDOM or not.
PS : Please check in the dev tools (Google chrome) if we have unique entry in HTML DOM or not.
Steps to check:
Press F12 in Chrome -> go to element section -> do a CTRL + F -> then paste the xpath and see, if your desired element is getting highlighted with 1/1 matching node.
once we have unique matching xpath. you can try to click on it by below methodology.
Code trial 1 :
time.sleep(5)
driver.find_element_by_xpath("//td[text()='RELATÓRIOS' and contains(#onclick,'abreMenu')]").click()
Code trial 2 :
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//td[text()='RELATÓRIOS' and contains(#onclick,'abreMenu')]"))).click()
Code trial 3 :
time.sleep(5)
button = driver.find_element_by_xpath("//td[text()='RELATÓRIOS' and contains(#onclick,'abreMenu')]")
driver.execute_script("arguments[0].click();", button)
Code trial 4 :
time.sleep(5)
button = driver.find_element_by_xpath("//td[text()='RELATÓRIOS' and contains(#onclick,'abreMenu')]")
ActionChains(driver).move_to_element(button).click().perform()
Imports :
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.webdriver.common.action_chains import ActionChains
I'm having an issue clicking an icon/link in a table. I've tried both find_element_by_xpath and find_elements_by_Xpath - no luck with either. I forced the wait as I was getting some issues with the element not being found.
I've highlighted the icon in the Table row, with the red box. in this image.
Website
Also found the Xpath but can't seem to get it to work, the icon is clickable on the webpage.
Xpath
My code is below:
driver.implicitly_wait(7)
tr = driver.find_element_by_xpath('//*[#id="AthleteTheme_wt6_block_wtMainContent_wt9_wtClassTable_ctl05_AthleteTheme_wt221_block_wtIconSvg_Svg"]/svg/use')
tr.click()
Thanks
The Element is in an svg tag. And there is a different syntax for the same. Links to refer - Link1, Link2
To access svg tag elements the syntax would something like this:
//*[local-name()='svg']
As per the screen shot the xpath for the Elements would be:
//span[#id="AthleteTheme_wt6_block_wtMainContent_wt9_wtClassTable_ctl05_AthleteTheme_wt221_block_wtIconSvg_Svg"]/*[local-name()='svg']/*[local-name()='use']
You can not directly use // to locate an SVG element. They are one of the special tags.
Always use //*[name()='svg'] or //*[local-name()='svg'] to locate them.
Based on the HTML that you've shared, Please use the below xpath :
//a[#class='svgContainer']//child::span//*[name()='svg' and starts-with(#id,'AthleteTheme')]//*[name()='use']
** Please check in the dev tools (Google chrome) if we have unique entry in HTML DOM or not.
Steps to check:
Press F12 in Chrome -> go to element section -> do a CTRL + F -> then paste the xpath and see, if your desired element is getting highlighted with 1/1 matching node.
Code trial 1 :
time.sleep(5)
driver.find_element_by_xpath("//a[#class='svgContainer']//child::span//*[name()='svg' and starts-with(#id,'AthleteTheme')]//*[name()='use']").click()
Code trial 2 :
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//a[#class='svgContainer']//child::span//*[name()='svg' and starts-with(#id,'AthleteTheme')]//*[name()='use']"))).click()
Code trial 3 :
time.sleep(5)
button = driver.find_element_by_xpath("//a[#class='svgContainer']//child::span//*[name()='svg' and starts-with(#id,'AthleteTheme')]//*[name()='use']")
driver.execute_script("arguments[0].click();", button)
Code trial 4 :
time.sleep(5)
button = driver.find_element_by_xpath("//a[#class='svgContainer']//child::span//*[name()='svg' and starts-with(#id,'AthleteTheme')]//*[name()='use']")
ActionChains(driver).move_to_element(button).click().perform()
Imports :
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.webdriver.common.action_chains import ActionChains