I want to select an item from a drop down using selenium python. The project uses react.js. The dropdown html appears in a div.
code inspect for dropdown
As this is under div, not select, when i try to select specific value, i got an error message.
Error message:
selenium.common.exceptions.UnexpectedTagNameException: Message: Select
only works on elements, not on div
How can I solve this issue?
You cannot use Select class to operate dropdowns which are not implemented using select and option elements.
You have to handle this kind of dropdown "manually" - generally speaking - click it to open it up, locate the desired dropdown item/option and click it. E.g., judging by you concise HTML snippet, to open up the dropdown you can try:
# open up the dropdown
dropdown = driver.find_element_by_css_selector(".Select-control")
# or dropdown = driver.find_element_by_css_selector(".Select-control .Select-input")
dropdown.click()
# TODO: select option
Sometimes, simply focusing the dropdown and typing the desired item/option text would auto-select it - if this is the case, you can try:
from selenium.webdriver.common.action_chains import ActionChains
actions = ActionChains(driver)
actions.move_to_element(dropdown).send_keys("Desired option text").perform()
And, if there are any animations or time delays (to, for example, retrieve the options from the server) you may need to add Explicit Waits to handle the possible timing issues.
These are all general tips, I am operating under assumptions and I have no way to check if anything above works for your use case.
Related
I'm kinda new at Selenium, so a proposed myself a project. I'm trying to get as much information as I can from this URL https://statusinvest.com.br/acoes/proventos/ibovespa
Until that time I was able to do everything, EXCEPT change the default option at the "Filtro por Índice". I would like to change it from "Ibovespa" to "--GERAL--" but it has been harder than I would expect! I tried via classical XPath (find then click) and by the Select() class in Selenium, but it appears to be beyound my knowledge and I'm totally stuck...
Anyone has any tip on how to accomplish it?
Thanks!
So a very simple way to change the input option would be to do:
from selenium.webdriver.common.by import By
select_obj = driver.find_element(By.CLASS_NAME, 'select-wrapper') # object that contains all of the elements for first input selector
select_obj.find_element(By.TAG_NAME, 'input').click() # click the input object to bring up the options
select_obj.find_elements(By.TAG_NAME, 'li')[0].click() # click the first option
I am a beginner in python web scraping and trying to automate the site. In the website which I want to scrape there is a searching filter, where I am applying filters on input box dropdown tag.
in the drop-down box, I write the country name and all country come accordingly but I am unable to select or click the very first country that comes as a value in the dropdown box. I applied some code also but my script fails and terminated.
Below is the image for better understanding.
enter image description here
I also applied some code, please check below
p_location='united states'
browser.find_by_xpath("//label[contains(.,'Geography')]").first.click()
actions_wait_time = randint(15, 30)
time.sleep(actions_wait_time)
loc_input = browser.find_by_xpath("//input[#placeholder='Add locations']")
loc_input.type(p_location)
actions_wait_time = randint(15, 30)
time.sleep(actions_wait_time)
loc_input.type(Keys.TAB)
time.sleep(3)
loc_input.type(Keys.RETURN)
I want to select the first value from the dropdown list. Please help
It's not possible to come up with the exact code without seeing the DOM of the page, however one thing is obvious: you should not be using time.sleep function as it is a some form of a performance anti-pattern.
You should go for Explicit Wait instead like:
loc_input = WebDriverWait(browser, 10).until(EC.presence_of_element_located((By.XPATH, "//input[#placeholder='Add locations']")))
first_element = WebDriverWait(browser, 10).until(EC.presence_of_element_located((By.XPATH, "//xpath/for/the/first/element/in/the/dropdown")))
first_element.click()
More information: How to use Selenium to test web applications using AJAX technology
So I know that when I have DEBUG in my Django settings set to False, Selenium fails to have access to the static files, resulting in something looking like:
However, when I run my Selenium tests regardless they are able to interact with the DOM and select items from the dropdown! The test code I have is currently
from selenium.webdriver import Chrome
from selenium.webdriver.support.ui import Select
from selenium import webdriver
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
from urllib.parse import urljoin
import time
driver = webdriver.Chrome()
driver.get("localhost:8000/")
time.sleep(3)
driver.find_element_by_id('select-dance').click()
select = Select(driver.find_element_by_xpath('//*[#id="select-dance"]'))
select.select_by_value('1')
driver.find_element_by_id('select-date-range').click()
select = Select(driver.find_element_by_xpath('//*[#id="select-date-range"]'))
select.select_by_value('1')
driver.find_element_by_id('location').click()
When I set DEBUG to True, the page renders how I want it to because it has access to the static files. But whenever I try to run the tests I always get the error
selenium.common.exceptions.ElementNotVisibleException: Message: element not interactable
This seems to happen for any element I refer to. For some reason, when I try to click on the dropdown directly, it always highlights this input and the select tag always seems to be 'hidden', so I wonder if that may be causing the error
Thank you all for your help, I don't know why Selenium is not being allowed to directly access the select tag for drop down.
Your page uses custom Select Component which is not the default html select box. In your case, they have used MDBootstrap Select Component which cannot be interacted using selenium Select class
You are right. You are trying to interact with <select> dom which is not visible and it is throwing element not visible exception.
We have two automate this case exactly similar like the manual steps,
i.e.,
Click the element which is intractable.
Wait for the dropdown appears.
Click the value from the dropdown.
In your case for selecting first value in dance select box, the code can rewritten as below.
# this is click the input element which is intractable
# Here the input box which contains value 'dance event' is clicked
driver.find_element_by_css_selector('input.select-dropdown[value*="dance event"]').click
# Then we are waiting for the first value of the dropdown which is not disabled
wait = WebDriverWait(driver, 60)
element = wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, 'input.select-dropdown[value*="dance event"]+ul>li:not(.disabled)')))
# Click the element first value of the dropdown
element.click()
I'm using Selenium with Python to use this website and want to change page by clicking on the button designed for that. However, and I don't know why, this button is disabled and becomes enabled only if you choose another number of items to be displayed on the page.
I managed to programmatically click on the list to display all the options but didn't manage to select an option.
I tried with the following lines:
driver.find_element_by_xpath("//*[#id='edit-limit']/option[2]").click()
driver.find_element_by_xpath("//select[#id='edit-limit']/option[2]").click()
driver.find_element_by_link_text('50').click()
Does someone know how to solve this issue?
I will give a method for selecting option by value from dropdown list or select:
def set_select_element(self, element, val):
element = ui.Select(element)
return element.select_by_visible_text(val)
where element -- this is your select element on the page.
I have a form which has two drop-down menu say A and B. Contents of drop-down B is dependent on the selection of drop-down A.
The form uses AJAX to load the contents of drop down B.
I am using selenium and python to automatically select the drop down. I am able to select the drop down A but due to the use of AJAX my code is not working for selecting the content of drop-down B.
I have searched the selenium documentation (Explicit wait) and some stackoverflow answers but still I am unable to implement it in python. I am a newbie in python and selenium so please bear me.
Here is a small portion of my code :
#District selection DROP-DOWN A
district=Select(driver.find_element_by_id("ddlDistrict85"))
district.select_by_value("1")
#SRO selection DROP-DOWN B
# I Need EXPLICIT WAIT logic here to wait till the entire drop-down B is loaded
sro=Select(driver.find_element_by_id("ddlSRO85"))
sro.select_by_value("1")
Suggest some logic to wait till entire drop-down B is loaded.
You can use the options attribute from Select to check you have elements in the dropdown
district=Select(driver.find_element_by_id("ddlDistrict85"))
district.select_by_value("1")
sro=Select(driver.find_element_by_id("ddlSRO85"))
while len(sro.options) == 0:
continue
sro.select_by_value("1")
You haven't shared what the html looks like for these different menus, so let me assume that drop-down B is wrapped by a DIV with a specific class, or even better an ID, perhaps:
<div id="menuB"> ... </div>
Now, you could use Expected Conditions to wait for that menu to appear.
from selenium.webdriver.support import expected_conditions as EC
wait = WebDriverWait(driver, 10)
element = wait.until(EC.visibility_of_element_located((By.ID,'menuB')))
After searching a lot I found a simple solution where I am able to select the contents of drop-down B.
So I am answering my own question.
Use sleep function from time module to pause the execution of the program for some time(in seconds).
The program code would go like this :
import time #To import time module
#District selection
district=Select(driver.find_element_by_id("ddlDistrict85"))
district.select_by_value("1")
#SRO selection
time.sleep(5)
sro=Select(driver.find_element_by_id("ddlSRO85"))
sro.select_by_value("1")
It's working now.