How to select a value from dropdown in Selenium? - selenium

Sorry if the question has been asked before. But I am just starting with programming and Selenium.: I need help with selecting a value from the below drop down:
Below is the HTML Code
I tried to select Delhi by using its xpath:
driver.findElement(By.xpath("//div[#id='glsctl00_mainContent_ddl_destinationStation1_CTNR']//a[#text='Delhi (DEL)'][contains(text(),'Delhi (DEL)')]")).click();
The error I got in console is:
"no such element: Unable to locate element: {"method":"xpath","selector":"//div[#id='glsctl00_mainContent_ddl_destinationStation1_CTNR']//a[#text='Delhi (DEL)'][contains(text(),'Delhi (DEL)')]"}"
Can you please help me, what is the other way to select a value from this dropdown?

driver.maximize_window()
wait = WebDriverWait(driver, 10)
wait.until(EC.element_to_be_clickable((By.XPATH, "//input[#id='ctl00_mainContent_ddl_originStation1_CTXT']"))).click()
wait.until(EC.element_to_be_clickable((By.XPATH, "//div[#id='dropdownGroup1']//div[#class='dropdownDiv']//ul//li//a[#text='Delhi (DEL)']"))).click()
wait.until(EC.element_to_be_clickable((By.XPATH, "//div[#id='glsctl00_mainContent_ddl_destinationStation1_CTNR']//a[#text='Goa (GOI)'][contains(text(),'Goa (GOI)')]"))).click()
Note : please add below imports to your solution
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait

Related

select element in selenium using partial xcode or partial css selector

I am trying to select a certain element in a webpage in selenium. I know that the element's name looks like person_xxxxx with xxxx being random numbers. I would like to know if it is possible to select this element using xpath or css selector. So far I have tried:
cartes_profils=liste_profils_shadow.find_elements_by_xpath('//*[contains(#id,"person_")]')
which is deprecated and doesn't work
cartes_profils=liste_profils_shadow.find_elements(by=By.CSS_SELECTOR,value='input[id^="#person_"]')
which runs but doesn't select the desired elements
cartes_profils=liste_profils_shadow.find_elements(by=By.XPATH,value=("//*[contains(#id, 'person_')]"))
which returns an "invalid selector" error
PS: I know that there are similar topics already answered but they are all a million years old and the solutions do not work for me
You should ideally be using starts-with for xpath. Also, yes you are right
find_elements_by_*** is deprecated in selenium 4. You should use find_element(By.XPATH, "")
so your effective xpath would be:
//*[starts-with(#id,'person_')]
use it like
driver.find_element(By.XPATH, "//*[starts-with(#id,'person_')]")
and equivalent CSS would be: (you are fairly close here)
input[id^="person_"]
use it like
driver.find_element(By.CSS_SELECTOR, "input[id^="person_"]")
My recommendation would be explicit waits:
element = WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//*[starts-with(#id,'person_')]")))
You'll have to import these for explicit waits:
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC

Finding XPATH for an DOB

I am not able to locate the xpath for the DOB field for the following page as the right click is disabled in the DOB calendar. Any leads will be helpful.
For example, I am trying to select the DOB as 1st Mar,2004
https://pos-diy.iiflinsurance.com/form/proposer-form?quote_id=dARV3Hz22VvXFwtRy5Ev
You don't really need to click on the Calendar and then Select a date.
You can parse the value using execute_script
Code:
driver.get("https://pos-diy.iiflinsurance.com/form/proposer-form?quote_id=dARV3Hz22VvXFwtRy5Ev")
wait = WebDriverWait(driver, 30)
wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, "input[placeholder='Full Name']"))).send_keys('Apratim Chaudhuri')
dob = wait.until(EC.visibility_of_element_located((By.XPATH, "//input[#type='date']")))
driver.execute_script("arguments[0].value = arguments[1]", dob, "2004-03-01")
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 XPath expression will match:
"//input[#formcontrolname='dob']"
Or even this
"//input[#formcontrolname]"

Web-scraping dynamic website with user input using Selenium and Python

As A Swimmer, I am trying to pull times from a table that can be accessed after the User Inputs their name or other optional fields. The website dynamically generates this data. Below is my current code which does not factor in user inputs.
I am very confused about how selenium's automation works and how to find the right text field for it to read my results and for the rest of my code to extract the table.
Can anyone give some advice on how to proceed?
Any help is appreciated and thanks in advance.
This Is My Current Code:
from selenium import webdriver
from bs4 import BeautifulSoup
import pandas as pd
options = webdriver.ChromeOptions()
options.add_argument('--headless')
options.add_argument('--no-sandbox')
options.add_argument('--disable-dev-shm-usage')
site = 'https://www.swimming.org.nz/results.html'
wd = webdriver.Chrome( "C:\\Users\\joseph\\webscrape\\chromedriver.exe")
wd.get(site)
html = wd.page_source
df = pd.read_html(html)
df[1].to_csv('Results.csv')
To start with you need to send a character sequence to the Swimmer field.
To send a character sequence to the Swimmer field as the elements are 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.swimming.org.nz/results.html")
WebDriverWait(driver, 20).until(EC.frame_to_be_available_and_switch_to_it((By.CSS_SELECTOR,"iframe#iframe")))
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "input[id^='x-MS_FIELD_MEMBER']"))).send_keys("Joseph Zhang")
Using XPATH:
driver.get("https://www.swimming.org.nz/results.html")
WebDriverWait(driver, 20).until(EC.frame_to_be_available_and_switch_to_it((By.XPATH,"//iframe[#id='iframe']")))
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//input[starts-with(#id, 'x-MS_FIELD_MEMBER')]"))).send_keys("Joseph Zhang")
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
Browser Snapshot:
References
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

find_element_by_class_name in selenium giving error

I am trying to automate a button click using selenium but it is giving me the error. The html code of the page is:
The code i am trying is:
create_team=driver.find_element_by_class_name('ts-btn ts-btn-fluent ts-btn-fluent-secondary ts-btn-fluent-with-icon join-team-button')
create_team.click()
I am getting the following error:
driver.find_element_by_class_name() only accepts one className, it's not built to handle multiple classNames, reference - (How to locate an element with multiple class names?), THIS SEEMS TO BE UP FOR DEBATE
Use driver.find_element_by_css_selector('ts-btn.ts-btn-fluent.ts-btn-fluent-secondary.ts-btn-fluent-with-icon.join-team-button')
With driver.find_element_by_css_selector you can chain multiple classNames together using a dot(.) between each className in the selector.
To click on the element you can use either of the following Locator Strategies:
Using css_selector:
driver.find_element_by_css_selector("button.ts-btn.ts-btn-fluent.ts-btn-fluent-secondary.ts-btn-fluent-with-icon.join-team-button[data-tid='tg-discover-team']").click()
Using xpath:
driver.find_element_by_xpath("//button[#class='ts-btn ts-btn-fluent ts-btn-fluent-secondary ts-btn-fluent-with-icon join-team-button' and #data-tid='tg-discover-team']").click()
As the desired element is an Angular element, 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, "button.ts-btn.ts-btn-fluent.ts-btn-fluent-secondary.ts-btn-fluent-with-icon.join-team-button[data-tid='tg-discover-team']"))).click()
Using XPATH:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//button[#class='ts-btn ts-btn-fluent ts-btn-fluent-secondary ts-btn-fluent-with-icon join-team-button' and #data-tid='tg-discover-team']"))).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
create_team=driver.find_element_by_class_name('ts-btn.ts-btn-fluent.ts-btn-fluent-secondary ts-btn-fluent-with-icon.join-team-button')
create_team.click()
You have to replace space with . as space indicate multiple class
You can use xpath or css also:
create_team=driver.find_element_by_xpath("//*[#class='ts-btn.ts-btn-fluent.ts-btn-fluent-secondary ts-btn-fluent-with-icon.join-team-button]')
create_team.click()
create_team=driver.find_element_by_css_selector("[class='ts-btn.ts-btn-fluent.ts-btn-fluent-secondary ts-btn-fluent-with-icon.join-team-button]')
create_team.click()
More to answer
If you check the exception from the by_class_name:
You can see that it is using css_class locator under the hood ( You can see it add . in frontautomatically)
Working example:
from selenium import webdriver
import time
from selenium.webdriver.support import expected_conditions as EC
driver = webdriver.Chrome()
driver.get("https://stackoverflow.com/questions/65579491/find-element-by-class-name-in-selenium-giving-error/65579606?noredirect=1#comment115946541_65579606")
time.sleep(5)
elem = driver.find_element_by_class_name('overflow-x-auto.ml-auto.-secondary.grid.ai-center.list-reset.h100')
print(elem.get_attribute("outerHTML"))

Having trouble finding element on page with xpath

I am trying to access the data as shown below.
I am using this command to capture the information but to no avail. Does anyone have any tips on where I'm going wrong?
Code trials:
posts = firefox.find_elements_by_xpath(//*[#id="flotGagueValue0"])
print(posts)
for post in posts:
print(post)
You are looking for ".text".
posts = firefox.find_elements_by_xpath(//*[#id="flotGagueValue0"]) print(posts) for post in posts: print(post.text)
I would write it like this for readability:
posts = firefox.find_elements_by_xpath(//*[#id="flotGagueValue0"])
for post in posts:
print(post.text)
The desired element is an Angular element so to extract the text 98.72 you have to induce WebDriverWait for the visibility_of_element_located() and you can use either of the following solutions:
Using CSS_SELECTOR and text attribute:
print(WebDriverWait(firefox, 20).until(EC.visibility_of_element_located((By.CSS_SELECTOR, "div.panel-content div.singlestat-panel > div span#flotGagueValue0"))).text)
Using XPATH and get_attribute():
print(WebDriverWait(firefox, 20).until(EC.visibility_of_element_located((By.XPATH, "//div[#class='panel-content']//div[#class='singlestat-panel']/div//span[#id='flotGagueValue0']"))).get_attribute("innerHTML"))
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