find_element() with Link_Text not working using Selenium Python - python

I am new to selenium whenever I try to find elements using id, name , xpath or anything it gives the same error
from selenium import webdriver
driver = webdriver.Safari()
driver.get('https://www.lambdatest.com/blog/selenium-safaridriver-macos/')
driver.find_element(By.Link_Text,'Webinar' )
It shows error by underlining By.
I tried writing
driver.find_element_by_id('Webinar')
But it does not go through I tried different websites and with different elements like class, id but seems like there is a problem with finding elements by any method is there something that needs to installed to make it work?

You have to take care of a couple of things here:
The supported locator strategy should be LINK_TEXT instead of Link_Text
The link_text should be Webinars instead of Webinar.
Effectively, your line of code should be:
driver.find_element(By.LINK_TEXT, 'Webinars' )
However, within the webpage there are multiple elements with innerText as Webinars. So you need to use a locator strategies which identifies the element uniquely within the DOM.
Solution
Ideally, to locate the clickable element from the menu container with text as Webinars you need to induce WebDriverWait for the element_to_be_clickable() and 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, "div.menu-menu-1-container a[href='https://www.lambdatest.com/webinar/']")))
Using XPATH:
element = WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//div[#class='menu-menu-1-container']//a[text()='Webinars']")))
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

This
driver.find_element(By.Link_Text,'Webinar')
should be
driver.find_element(By.LINK_TEXT, 'Webinar')
Also, Import this from selenium.webdriver.common.by import By
If you are on Selenium4 then you should not really use:
driver.find_element_by_id('Webinar')
use this instead:
driver.find_element(By.ID, 'Webinar')
If you take a look at the source code, you'd see:
class By(object):
"""
Set of supported locator strategies.
"""
ID = "id"
XPATH = "xpath"
LINK_TEXT = "link text"
PARTIAL_LINK_TEXT = "partial link text"
NAME = "name"
TAG_NAME = "tag name"
CLASS_NAME = "class name"
CSS_SELECTOR = "css selector"

Related

Selenium - find id based on class tag

I want to find with Selenium (python) an id based on a class tag
I want to find the result of a html form. There are 2 results possible, available or not available.
Both options will appear in the html code, but two different CSS format will be used to show the result and to hide the other option.
I would like to get the id (either "WarningDisponible" or "WarningIndisponible") based on the div class "Content Warning" (this is the result), "Content Warning hidden" is not the result.
This website should help: https://selenium-python.readthedocs.io/locating-elements.html
Search the div first with ContentWarning = driver.find_element_by_class_name('Content Warning')
From there you can just search within the div by checking if ContentWarning.find_element_by_id('WarningDisponible') returns any results.
This does assume that there are no other elements in the HTML with the class name 'Content Warning' other than the div you are looking for.
Another simple way is to give complete xpath. This way, you can avoid confusion
Select(driver.find_element(by=By.XPATH,value='your_complete_xpath')
and then as per your need send_keys() or select_by_value("your_value_here").
To print the value of the id attribute i.e. WarningIndisponible based on the classname Content warning you can use either of the following Locator Strategies:
Using css_selector:
print(driver.find_element(By.CSS_SELECTOR, "div.Content.warning > p").get_attribute("id"))
Using xpath:
print(driver.find_element(By.XPATH, "//div[#class='Content warning']/p").get_attribute("id"))
Ideally you need to induce WebDriverWait for the visibility_of_element_located() and you can use either of the following Locator Strategies:
Using CSS_SELECTOR:
print(WebDriverWait(driver, 20).until(EC.visibility_of_element_located((By.CSS_SELECTOR, "div.Content.warning > p"))).get_attribute("id"))
Using XPATH:
print(WebDriverWait(driver, 20).until(EC.visibility_of_element_located((By.XPATH, "//div[#class='Content warning']/p"))).get_attribute("id"))
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 click on the span element using Selenium and 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.

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