How to click on the span element using Selenium and Python - python

I'm trying to identify the following element but no matter the method it doesn't see it.
<span onclick="onClickTab('details'); return false;" id = "details" name = "details" class style ="display: inline;"">...</span>
I've tried with: Xpath, relative xpath, onclick, onclick contains, by id, by name, just nothing works.
It is a clickable button which appears after selecting an item in a list.
Current code is:
try:
WebDriverWait(driver,30).until(EC.presence_of_element_located((By.XPATH,"//span[#onclick='onClickTab('details'); return false;']")))
except
print("Error")
driver.find_element_by_xpath("//span[#onclick='onClickTab('details'); return false;']").click()
if there are any minor syntax problems like a "(" or such it might be because I typed it by hand, that shouldn't be the issue.
I'm forever grateful if you could point me to the right direction.

To click on the <span> element instead of presence_of_element_located() you have to induce WebDriverWait for the element_to_be_clickable() and you can use either of the following Locator Strategies:
Using CSS_SELECTOR:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "span#details[name='details'][onclick^='onClickTab']"))).click()
Using XPATH:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//span[#id='details' and #name='details'][starts-with(#onclick, 'onClickTab')]"))).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

I was able to select the element using the following xPath:
//span[contains(#onclick, "onClickTab(\'details\'); return false;")]
Using selenium, I used:
try:
WebDriverWait(driver, 30).until(EC.presence_of_element_located((By.XPATH,'//span[#onclick="onClickTab(\'details\'); return false;"]')))
except:
print("Error")
driver.find_element_by_xpath('//span[#onclick="onClickTab(\'details\'); return false;"]').click()

Here i suggest you to use id in Xpath.
driver.find_element_by_xpath("//span[contains(#id,'details')]").click()
if multiple element is there then you have to use foreach loop of driver.find_elements_by_xpath("//span[contains(#id,'details')]") and check with text and click on match element.

Related

How to interact with button based on text using Selenium and Python

I'm trying to click buttons based on their text (using selenium). e.g., for the following HTML tag:
<span class="MuiTab-wrapper jss483">Options</span>
I've tried:
driver.find_elements_by_xpath("//*[contains(text(), 'Options')]").click()
However, Selenium can't find any element with the text: "Options".
Any ideas?
Please check in the dev tools (Google chrome) if we have unique entry in HTML DOM or not.
xpath that you should check :
//*[contains(text(), 'Options')]
or
//span[contains(text(), 'Options')]
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.
There are 4 ways to click in Selenium.
Code trial 1 :
time.sleep(5)
driver.find_element_by_xpath("//span[contains(text(), 'Options')]").click()
Code trial 2 :
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//span[contains(text(), 'Options')]"))).click()
Code trial 3 :
time.sleep(5)
button = driver.find_element_by_xpath("//span[contains(text(), 'Options')]")
driver.execute_script("arguments[0].click();", button)
Code trial 4 :
time.sleep(5)
button = driver.find_element_by_xpath("//span[contains(text(), 'Options')]")
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
Also, find_elements returns a list, change that to find_element you should be good to go ahead.
or else use list index to point web element.
elems = driver.find_elements_by_xpath("//*[contains(text(), 'Options')]")
elems[0].click()
This is not recommended way.
You are using find_elements_by_xpath method. It will give you a list of web elements, not a single web element. So you can not apply .click() on the result of
driver.find_elements_by_xpath("//*[contains(text(), 'Options')]")
You should use find_element_by_xpath instead so your code will be
driver.find_element_by_xpath("//*[contains(text(), 'Options')]").click()
or clicking on the first result (or any other) from the web elements list returner, as following
driver.find_elements_by_xpath("//*[contains(text(), 'Options')]")[0].click()
Also possibly you need to add some delay / wait to let the element be loaded before accessing it.
Or maybe you need to scroll that element into the view.
Or maybe the element is inside an iframe...
To click on the element with text as Options you can use either of the following Locator Strategies:
Using xpath:
driver.find_element(By.XPATH, "//span[contains(#class, 'MuiTab-wrapper') and contains(., 'Options')]").click()
The desired element is a JavaScript enabled element, so ideally, to click on the element you need to induce WebDriverWait for the element_to_be_clickable() and you can use either of the following Locator Strategies:
Using XPATH:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//span[contains(#class, 'MuiTab-wrapper') and contains(., 'Options')]"))).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

Cant find element with Selenium

I am trying to create a scraper for Etsy shop managers but after I log in I am unable to use the code to locate the shop manager button(NoSuchElement). Here is my code:
from selenium import webdriver
options = webdriver.ChromeOptions()
options.add_argument('--incognito')
driverLocation = 'Downloads/chromedriver'
driver = webdriver.Chrome(driverLocation)
driver.get("https://www.etsy.com/signin")
username = driver.find_element_by_id("join_neu_email_field")
username.clear()
username.send_keys("username")
password = driver.find_element_by_id("join_neu_password_field")
password.clear()
password.send_keys("password")
driver.find_element_by_name("submit_attempt").click()
driver.implicitly_wait(10)
driver.find_element_by_class_name("wt-display-inline-flex-xs wt-flex-direction-column-xs wt-align-items-center wt-text-link-no-underline wt-p-xs-2 wt-pt-lg-0 wt-pb-lg-0 wt-pl-lg-1 wt-pr-lg-1 ge-nav-link reduced-margin-xs").click()
driver.quit()
The button I am trying to locate on the website:
I've tried various different methods(xpath, class_name, css_selector). I only see the class name as an identifier so I am not sure why its not working.
You should not use class name here because this class looks pretty much dynamic.
Using href attribute value in xpath is also not suggested.
In this case you should write an xpath with respect to some element which has static attribute or text. I feel there is a text in span tag so here you can try - //span[text()='putTheTextValue']/parent::a
Put a 5sec wait before interacting to this element just to make sure it is loaded when you are looking for this element. Later you can adjust this.
driver.find_element_by_class_name("wt-display-inline-flex-xs.wt-flex-direction-column-xs.wt-align-items-center.wt-text-link-no-underline.wt-p-xs-2.wt-pt-lg-0.wt-pb-lg-0.wt-pl-lg-1.wt-pr-lg-1.ge-nav-link.reduced-margin-xs").click()
Space in class shows that it's multiple classes you have to replace space with dot
Else use xpath or css
driver.find_element_by_xpath("//*[#class=\"wt-display-inline-flex-xs wt-flex-direction-column-xs wt-align-items-center wt-text-link-no-underline wt-p-xs-2 wt-pt-lg-0 wt-pb-lg-0 wt-pl-lg-1 wt-pr-lg-1 ge-nav-link reduced-margin-xs\"]").click()
driver.find_element_by_cssSelector("[class=\"wt-display-inline-flex-xs wt-flex-direction-column-xs wt-align-items-center wt-text-link-no-underline wt-p-xs-2 wt-pt-lg-0 wt-pb-lg-0 wt-pl-lg-1 wt-pr-lg-1 ge-nav-link reduced-margin-xs\"]").click()
This will select element that has attribute class with exact value
The <a> element have a child <span>. So to click on the element you can use either of the following Locator Strategies:
Using css_selector:
driver.find_element_by_css_selector("a[href^='https://www.etsy.com/your/shops/me/dashboard'] > span").click()
Using xpath:
driver.find_element_by_xpath("//button[#class='save' and text()='save']").click()
Ideally, to click on the element you need to induce WebDriverWait for the element_to_be_clickable() and you can use either of the following Locator Strategies:
Using CSS_SELECTOR:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "a[href^='https://www.etsy.com/your/shops/me/dashboard'] > span"))).click()
Using XPATH:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//a[starts-with(#href, 'https://www.etsy.com/your/shops/me/dashboard')]/span"))).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

How to find the element using selenium in python

I can't find the element of the html below.
<span class="tabComboBoxName" id="tab-ui-id-1565209097494" aria-hidden="true">20/07/2019</span>
I've tried the following codes:
elem = browser.find_elements_by_xpath("//class[#id='tab-ui-id-1565209097494']")
elem = browser.find_elements_by_class_name('tabComboBoxName')
elem = browser.find_elements_by_id('tab-ui-id-1565209097494')
For those tries I got an empty list.
The element is a dynamically generated element so to locate the element you need to induce WebDriverWait for the desired visibility_of_element_located() and you can use either of the following Locator Strategies:
Using CSS_SELECTOR:
element = WebDriverWait(driver, 20).until(EC.visibility_of_element_located((By.CSS_SELECTOR, "span.tabComboBoxName[id^='tab-ui-id-']")))
Using XPATH:
element = WebDriverWait(driver, 20).until(EC.visibility_of_element_located((By.XPATH, "//span[#class='tabComboBoxName' and starts-with(#id, 'tab-ui-id-')][contains(., '20/07/2019')]")))
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
Make sure that the element doesn't belong to an <iframe>, if it does - you will need to switch_to() the iframe where the element lives prior to attempting to find it
Make sure that the element doesn't belong to ShadowDOM, if it does - you will need to locate the relevant ShadowRoot element, cast it to the WebElement and use find_element() function of the WebElement instead of driver
Make sure to use Explicit Wait as it might be the case the element is not immediately available and it's being loaded later via AJAX request
Try using another locator strategy, for instance you can stick to the element text like:
//span[text()='20/07/2019']

Selenium, select based on "onclick" value

With Selenium, I'm trying to find the following checkbox on webpage.
<input type="checkbox" value="1" onclick=" document.getElementById('lastCheminClicked').value='123'; createInputsBinaireCell(25,'colonne5',1,0789,1,1,0,this.checked, this);">
The distinctive part is the '123' value in the "onclick", this is what selenium should look for.
Any way to find it on page? I have tried with xpath with no sucess.
As you mentioned the partial value 123 is distinct within the onclick event so to locate the element you can use either of the following Locator Strategies:
Using CSS_SELECTOR:
element = WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "input[type='checkbox'][onclick*='123']")))
Using XPATH:
element = WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//input[#type='checkbox' and contains(#onclick,'123')]")))
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
XPath selectors allow using contains() function which can be used for partial match on the attribute or text value of the DOM element.
The relevant selector would be something like:
//input[contains(#onlclick, '123')]
Demo:
More information:
XPath Tutorial
XPath Axes
XPath Operators & Functions
You might try finding all input tags, and then iterate through each looking at the onclick attribute. For example:
from selenium.webdriver.common.by import By
input_tags = driver.find_elements(By.TAG_NAME, 'input')
found_tag = None
for input_tag in input_tags:
onclick_attribute = input_tag.get_attribute('onclick')
if ".value='123'" in onclick_attribute:
found_tag = input_tag
break
You'll probably need exception handling around the get_attribute call.

Python Selenium: can't figure out xpath to clickable link element in span tag

I'm using selenium python and have tried more than a dozen ways to find a clickable link element from a span tag but have been unsuccessful. I've tried using xpath, by link text, partial link text, and other suggestions researched.
The last 3 attempts using:
browser.find_element_by_link_text("Web Time Clock-Eastern").click()
element = browser.find_element_by_partial_link_text('Clock-Eastern')
browser.wait.until(EC.element_to_be_clickable((By.XPATH, '//a[#span]/html/body/div[6]/div[1]/div[1]/div[1]/div/div/div[4]/div[2]button'))).click()
I've provided image of the inspected element html below:
I expect to locate an element I can pass click method to open corresponding web page.
To click() the element you have to induce WebDriverWait for the element_to_be_clickable() and you can use either of the following solutions:
Using CSS_SELECTOR:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "div.cardLinks a[href*='php/timeclock/WEB'] > span"))).click()
Using XPATH:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//div[#class='cardLinks']//a[contains(#href, 'php/timeclock/WEB')]/span[text()='Web Time Clock-Eastern']"))).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
Try the below xpath.
//span[normalize-space(.)='Web Time Clock-Eastern']/parent::a
One of the main reasons for using XPath is when you don’t have a suitable id or name attribute for the element you wish to locate.
browser.find_element_by_xpath("//div[#class='cardLinks']/div/a").click()

Categories