SELECT option from dropdown using Selenium Python - python

been dealing with a countries dropdown using Selenium Python;
here is the Div tag of the drop-down menu:
<div cdk-overlay-origin="" class="mat-select-trigger ng-tns-c95-29"><div class="mat-select-value ng-tns-c95-29" id="mat-select-value-1"><span class="mat-select-placeholder mat-select-min-line ng-tns-c95-29 ng-star-inserted"></span><!----><!----></div><div class="mat-select-arrow-wrapper ng-tns-c95-29"><div class="mat-select-arrow ng-tns-c95-29"></div></div></div><!---->
and here is the Div tag for the targeted option:
<div class="mat-select-value ng-tns-c95-29" id="mat-select-value-1"><!----><span class="mat-select-value-text ng-tns-c95-29 ng-star-inserted" style=""><span class="mat-select-min-line ng-tns-c95-29 ng-star-inserted">MAROKO</span><!----><!----></span><!----></div><div class="mat-select-arrow-wrapper ng-tns-c95-29"><div class="mat-select-arrow ng-tns-c95-29"></div></div>
and here's the specific Span Tag for the targeted option
<span class="mat-select-min-line ng-tns-c95-29 ng-star-inserted">MAROKO</span><!----><!---->
the code used to select an option from that dropdown is :
Country=browser.find_element(By.ID, 'mat-select-value-1')
time.sleep(5)
drop=Select(Country)
time.sleep(5)
drop.select_by_visible_text("MAROKO")
output
Exception has occurred: UnexpectedTagNameException
Message: Select only works on <select> elements, not on <div>
File "C:\Users\test\form.py", line 31, in <module>
drop=Select(Country)
I went with drop.select_by_visible_text since I believe it's the only available option!
Imports used
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support.ui import Select
from selenium.webdriver.support import expected_conditions as EC
import time
I would appreciate any helpful comment.
Cheers
Tried this
specifcly this;
WebDriverWait(browser, 20).until(EC.element_to_be_clickable((By.XPATH, "//*[#id="mat-radio-2"]/label/span[1]/span[1][text()='MAROKO']"))).click()
but it seems that there's a syntax error

You can use the selenium's Select() class only for html <select> tags. But this dropdown is implemented with <div>, so you can handle it just like html elements.
First you need to click the dropdown to expand the options and then click the option you need:
WebDriverWait(browser, 10).until(EC.presence_of_element_located((By.XPATH, '//div[#class="mat-select-trigger ng-tns-c95-29"]'))).click()
WebDriverWait(browser, 10).until(EC.presence_of_element_located((By.ID, 'mat-select-value-1'))).click()
I've created the locators using the html parts you provided. Perharps you will need to update them.

Related

Selenium Select not working on dropdown element

So I am trying to run the following code to select an option from a drop-down toolbar:
## Drop-down menu
time.sleep(5) # wait for element to load in page otherwise selenium won't be able to find it
element_dropdown = driver.find_element("id","conference-dropdowns")
element_dropdown.click()
# Select visible text
time.sleep(5)
select = Select(element_dropdown)
select.select_by_visible_text("Bulk Upload")
But then I get the following error:
UnexpectedTagNameException: Message: Select only works on <select> elements, not on <label>
How do I resolve this issue? Why am I getting this error? See structure below. Thanks so much in advance.
The desired element isn't within any html-select tag, but they are within <label> tag.
So you won't be able to use Select() class.
Solution
The click element with text as Bulk Upload you need to induce WebDriverWait for the element_to_be_clickable() and you can use the following locator strategy:
Using XPATH:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//li[#class='dropdown-submenu']//label[#class='submenu' and contains(., 'Bulk Upload')]"))).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
The Exception says everything: you can use Select class only with <select> object.
Simply try to
click() on button to expand drop-down menu
wait for required option to be clickable
click() on option

Need help using selenium

I want to go to this site:
http://www.datiopen.it/it/opendata/Mappa_delle_stazioni_ferroviarie_in_Italia
Then click on the "Tabella" tab
Then see the second page (out of 64) of the table
However I failed in the first part, I cannot make a code to click on "Tabella" tab
import requests
from selenium import webdriver
driver.get('http://www.datiopen.it/it/opendata/Mappa_delle_stazioni_ferroviarie_in_Italia')
element = driver.find_element_by_id("Tabella")
element.click()
And here is the html code that I used to search:
<li id="Tabella" class="Table_img ui-state-default ui-corner-top ui-tabs-selected ui-state-active">
<span id="span_table_img" class="span_img"></span>
Tabella </li>
Thank all!
Add time sleep before accessing the table element.
time.sleep(5)
driver.find_element_by_id('Tabella').click()
To click on Tabella tab you need to induce WebDriverWait() and wait for element_to_be_clickable() and you can use following locator.
Link Text:
driver.get("http://www.datiopen.it/it/opendata/Mappa_delle_stazioni_ferroviarie_in_Italia")
WebDriverWait(driver,20).until(EC.element_to_be_clickable((By.LINK_TEXT,"Tabella"))).click()
XPATH:
driver.get("http://www.datiopen.it/it/opendata/Mappa_delle_stazioni_ferroviarie_in_Italia")
WebDriverWait(driver,10).until(EC.element_to_be_clickable((By.XPATH,"//a[text()='Tabella']"))).click()
You need to import below libraries.
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
Problem with your code
You are trying to click an element before it is available/ready to click in DOM.
Solution
You need to wait for the element to load and become clickable to perform any kind of action on the same element.
Code
driver = webdriver.Chrome()
driver.get('http://www.datiopen.it/it/opendata/Mappa_delle_stazioni_ferroviarie_in_Italia')
def wait_for_element_to_be_clickable(element):
WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.ID, element)))
wait_for_element_to_be_clickable("Tabella")
element = driver.find_element_by_id("Tabella")
element.click()
print("executed")
def wait_for_element_to_be_clickable(element): this method will wait for any element to become clickable before proceeding. (you can increase the time based on your page loading time).

How to click on GWT enabled elements using Selenium and Python

I'm working with Selenium as a newbie and also as a newbie developer.
I try to solve this XPath but with no results that is why I'm looking for help.
So I want to click in the checkbox which has a dynamic id but it is not that easy to find this checkbox based on tittle="Viewers"
Please notice there is a whole list of checkboxes with names on right from a checkbox in div which I want to include in my tests.
HTML:
<span class="row-selection"><input type="checkbox" value="on" id="gwt-uid-2215" tabindex="0"><label for="gwt-uid-2215"></label></span> <div class="row-label" title="Viewers">Viewers</div>
Snapshot;
The desired element is a GWT enabled element so to click on the element you have to induce WebDriverWait for the element_to_be_clickable() and you can use either of the following xpath based Locator Strategy:
Using xpath based on title attribute:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//div[#title='Viewers']//preceding::span[1]//label"))).click()
Using xpath based on innerHTML:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//div[text()='Viewers']//preceding::span[1]//label"))).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

Python Finding element by XPath

For reference visit https://rabirius.me/2020/02/14/bird-watching/ (not my website)
You may see a Like button there near a reblog button
I want python to click that but I get an error stating
selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"xpath","selector":"/html/body/div/div/div[2]/a"}
The code i wrote was
for posts in open_links:
bot.get(posts)
sleep(4)
bot.find_element_by_xpath('/html/body/div/div/div[2]/a').click()
sleep(2)
The HTML of the like button is
<div class="wpl-button like">
<a href="#" title="177 bloggers like this." class="like sd-button" rel="nofollow">
<span>Like</span>
</a>
</div>
Any Help would be Appreciated
An iframe is present on the page, so you need to first switch to that iframe and then operate on the element and its recommended to use explicit wait to wait for the element to be present on the page.
You can do it like:
for posts in open_links:
bot.get(posts)
driver.switch_to.frame(bot.find_element_by_tag_name('iframe'))
like_element = WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, "//div[contains(#class,'wpl-likebox')]//span[text()='Like']")))
like_element.click()
You need 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

UnexpectedTagNameException while clicking dropdown menu item

I'm trying to get Python / Selenium to properly click on a dropdown menu and select "IT" but the best I could do was find the element and get an error stating I couldn't input text on what I have found.
Basically, the user would click on that menu and select IT or type IT and press enter.
HTML code:
<div class="form-group">
<label class="col-md-3 control-label" for="id_tenant_group">Tenant group</label>
<div class="col-md-9">
<select name="tenant_group" nullable="true" class="netbox-select2-api form-control" data-url="/api/tenancy/tenant-groups/" data-filter-for-tenant="group_id" placeholder="None" id="id_tenant_group">
<option value="" selected>---------</option>
<option value="2">IT</option>
<option value="1">OT</option>
</select>
</div>
When I inspect the element, I can see there is a span element that triggers an event showing another span where finally my option can be seen.
I cannot select via visible text, because other menus also contain the same "---------" visible text.
I've captured a couple screenshots to illustrate the issue, hope that helps.
html code browser inspect
To be honest I am really lost, any suggestions will be much appreciated.
EDIT:
I've attempted the following:
tenant_g_element = Select(browser.find_element(By.XPATH, '//span[#id="select2-id_tenant_group-container"]'))
tenant_g_element.selectByVisibleText("IT")
But I've got the following error:
selenium.common.exceptions.UnexpectedTagNameException: Message: Select only works on <select> elements, not on span
Your first line is wrong. It should be something like this:
tenant_g_element = Select(browser.find_element(By.ID, 'id_tenant_group'))
because your has the attribute id="id_tenant_group". There is no need to use By.XPATH...if you have some reason to need that, then you'll need to look up how to specify an XPATH (note that //span is going to find a <span>, not a <select> for example).
This error message...
selenium.common.exceptions.UnexpectedTagNameException: Message: Select only works on elements, not on span
...implies that the element which you are passing to Select class is not a <select> node but a <span> element which isn't supported.
Seems your locator was identifying a <span> element instead of the <select> element. Hence you see the error. Additionally, selectByVisibleText() is not a valid Python method, instead you need to use select_by_visible_text().
Solution
To click on the option with text as IT, you have to induce WebDriverWait for the element_to_be_clickable() and you can use either of the following Locator Strategies:
Using CSS_SELECTOR and select_by_value():
tenant_g_element = Select(WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "select.netbox-select2-api.form-control#id_tenant_group[name='tenant_group']"))))
tenant_g_element.select_by_value("2")
Using XPATH and select_by_visible_text():
tenant_g_element = Select(WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//select[#class='netbox-select2-api form-control' and #id='id_tenant_group'][#name='tenant_group']"))))
tenant_g_element.select_by_visible_text("IT")
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
from selenium.webdriver.support.ui import Select
Your Xpath seems wrong. You are trying to locate a span tag but you should locate select element. Additionally you should apply webdriver wait for of select element
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import Select
select = Select(WebDriverWait(driver, 50).until(
EC.presence_of_element_located((By.ID, "id_tenant_group"))))
WebDriverWait(driver, 50).until(
EC.presence_of_element_located((By.XPATH, "//select[#id='id_tenant_group']/option[2]")))
WebDriverWait(driver, 50).until(EC.element_to_be_clickable((By.XPATH, "//select[#id='id_tenant_group']//options[contains(.,'IT')]")))
select.select_by_visible_text('IT')

Categories

Resources