2

I am trying to click a dropdown option that has a value ending with a particular string.

I only know how to do this when I have the full value, not just a partial string match.

Please help!

<select name="dropdown_selected_size_name" autocomplete="off" data-a-native-class="twister-dropdown-highlight" data-a-touch-header="Size" id="native_dropdown_selected_size_name" class="a-native-dropdown twister-dropdown-highlight">
        <option value="0,B0019WTTQE" class="dropdownAvailable" data-a-css-class="dropdownAvailable" id="native_size_name_0" data-a-id="size_name_0" data-a-html-content="6 B(M) US">
            6 B(M) US
        </option>
        <option value="1,B0019WO400" class="dropdownAvailable" data-a-css-class="dropdownAvailable" id="native_size_name_1" data-a-id="size_name_1" data-a-html-content="7 B(M) US">
            7 B(M) US
        </option>
</select>

Create Select object:

from selenium import webdriver
from selenium.webdriver.support.select import Select
browser = webdriver.Firefox()
browser.get('http://www.amazon.com/dp/B0019WTTQE')
select = Select(browser.find_element_by_id('native_dropdown_selected_size_name'))

Attempt one:

select.select_by_value('B0019WTTQE').click();

selenium.common.exceptions.NoSuchElementException: Message: Cannot locate option with value: B0019WTTQE

Attempt two:

select.select_by_value(re.compile(r'B0019WTTQE$')).click();

TypeError: argument of type '_sre.SRE_Pattern' is not iterable

Imran
  • 12,950
  • 8
  • 64
  • 79

1 Answers1

3

There is no built-in way to match a select option by regex.

You'll have to iterate over options and check each of them:

select = Select(browser.find_element_by_id('native_dropdown_selected_size_name'))

pattern = re.compile(r'B0019WTTQE$')
for option in select.options:
    value = option.get_attribute('value')
    if pattern.search(value):
        option.click()
        break

Another possible solution could be to use an ends-with CSS selector:

select = browser.find_element_by_id('native_dropdown_selected_size_name')

option = select.find_element_by_css_selector('option[value$=B0019WTTQE]')
option.click()

Note that there is also an ends-with() xpath function, but it is a part of XPath 2.0 which, from what I understand, browsers doesn't support. contains() is definitely not a direct alternative, but could also work for your use-case:

select = browser.find_element_by_id('native_dropdown_selected_size_name')

option = select.find_element_by_xpath('.//option[contains(@value, "B0019WTTQE")]')
option.click()
Community
  • 1
  • 1
alecxe
  • 462,703
  • 120
  • 1,088
  • 1,195
  • Thanks a lot for the detailed answer. Your second solution gives me the following error: AttributeError: Select instance has no attribute 'find_element_by_css_selector'. I had tried something along those lines too with the same result, and I also found no find_element methods in the [docs](http://selenium-python.readthedocs.org/en/latest/api.html#module-selenium.webdriver.support.select) – Imran Mar 02 '15 at 19:19
  • Looks like your fix wasn't saved? – Imran Mar 02 '15 at 19:28
  • @Imran nope, basically I've removed the `Select()` class instantiation - `select` is now just `browser.find_element_by_id('native_dropdown_selected_size_name')`. – alecxe Mar 02 '15 at 19:29