Shiji M
Shiji M

Reputation: 33

Python Selenium selecting option using Select (element not visible?)

I've tried to use a few approaches mentioned in similar questions with no luck. In the HTML source code there is clearly 'value' and 'text' properties, but I cannot seem to access those when I use selenium.webdriver to access these?

Note selection lead to change in data on the page...


Edit2:

Guy has pointed out below that the actual drop down maybe a element instead of the element. However using el.click() simply flickers and does not open the drop-down.


EDIT1: The and elements can now be identified but I am unable to make an selection. I believe the page is also in javascript and hence I'm unsure if this affects methods used.


Original post:

Webpage: https://www.racv.com.au/on-the-road/driving-maintenance/fuel-prices.html

HTML code of selection, for visibility, some options omitted:

<select name="filter-select-6" id="filter-select-6" class="js-dropdown js-select-map js-filter-select" data-filter="#filter-list-60 .js-tab-item" data-url="/bin/racv/fuelprice" style="display: none;" data-parsley-id="3">                            
    <option value="11" data-index="0">LRP</option>
    <option value="2" selected="true" data-index="0">Unleaded</option>
    <option value="3" data-index="0">Diesel</option>
    <option value="8" data-index="0">Premium Unleaded 98</option>
</select>

I believe I can select the Select element without problem:

from selenium import webdriver
from selenium.webdriver.support.ui import Select

url = 'https://www.racv.com.au/on-the-road/driving-maintenance/fuel-prices.html'
driver = webdriver.Chrome()
driver.get(url)
driver.implicitly_wait(20)

fuel_select = Select(driver.find_element_by_id('filter-select-6'))

When I print the options, I get:

for fuel_option in fuel_select.options:
    print(fuel_option)

<selenium.webdriver.remote.webelement.WebElement (session="9a10aa750fa59f4412e0bea4d7aae990", element="0.5927271524692566-2")>
<selenium.webdriver.remote.webelement.WebElement (session="9a10aa750fa59f4412e0bea4d7aae990", element="0.5927271524692566-3")>
<selenium.webdriver.remote.webelement.WebElement (session="9a10aa750fa59f4412e0bea4d7aae990", element="0.5927271524692566-8")>
<selenium.webdriver.remote.webelement.WebElement (session="9a10aa750fa59f4412e0bea4d7aae990", element="0.5927271524692566-11")>

Using select():

for fuel_option in fuel_select.find_elements_by_tag_name('option'):
    if fuel_option.text == "Diesel":
        fuel_option.select()

Error:

Traceback (most recent call last):
  File "C:/file.py", line 18, in <module>
    fuel_option.Select()
AttributeError: 'WebElement' object has no attribute 'select'

Using click() or using any of the select_by_xxx():

for fuel_option in fuel_select.find_elements_by_tag_name('option'):
    if fuel_option.text == "Diesel":
        fuel_option.click()

#or using select_by_xxx
fuel_select.select_by_value('8')

Error:

selenium.common.exceptions.ElementNotVisibleException: Message: element not interactable: Element is not currently visible and may not be manipulated
  (Session info: chrome=74.0.3729.169)
  (Driver info: chromedriver=74.0.3729.6 (255758eccf3d244491b8a1317aa76e1ce10d57e9-refs/branch-heads/3729@{#29}),platform=Windows NT 10.0.17134 x86_64)

Upvotes: 3

Views: 3692

Answers (1)

Nic Laforge
Nic Laforge

Reputation: 1876

Select is a wrapper around the WebElement, select() is not a valid method. Please refer to Select doc

Have you tried using select_by_value:

fuel_select = Select(driver.find_element_by_id('filter-select-6'))
fuel_select.select_by_value("8")

Or by visible text:

fuel_select = Select(driver.find_element_by_id('filter-select-6'))
fuel_select.select_by_visible_text("Premium Unleaded 98")

EDIT1
Try to click() first to make the dropdown visible:

el = driver.find_element_by_id('filter-select-6')
el.click()
fuel_select = Select(el)

EDIT2:
I believe your issue is more related to the fact that you use the css property style="display: none;" You should not be able to see the dropdown manually either.

Please refer to the css syntax doc for more detail

When using None: The element is completely removed

Might not be "ideal" but you can change the value of this property to make it visible again using:

driver.execute_script('arguments[0].style.display = "block";', el)

Code would then look like:

el = driver.find_element_by_id('filter-select-6')
driver.execute_script('arguments[0].style.display = "block";', el)

fuel_select = Select(el)
fuel_select.select_by_value("8")

EDIT3:
Just noticed you provided the website! Very useful. So the dropdown is hidden being another element and only made available once clicked.

Here's the code and it worked for me

from selenium import webdriver
from selenium.webdriver.common.touch_actions import TouchActions
from selenium.webdriver.support.ui import Select

# Get the first element and tap on it, note you might have to tap few time.
el = driver.find_element_by_css_selector('.chosen-single > div')
action = TouchActions(driver)
action.tap(el).perform()

# once the dropdown is open it does not seems that the Select el is the one to use
els = driver.find_elements_by_css_selector('.active-result')
for el in els:
    if el.text == 'Diesel':
        el.click()
        break

Upvotes: 3

Related Questions