Take the 2-minute tour ×
Software Quality Assurance & Testing Stack Exchange is a question and answer site for software quality control experts, automation engineers, and software testers. It's 100% free, no registration required.

I would like to select an <option> child of a <select> using the Python WebDriver.

I have a reference to the option WebElement I wish to select and have tried select() and click() methods but neither works.

What is the correct way to select an <option>?

share|improve this question
Oh dearie me, of course it works. It was my fault for calling click() on the default <option>, which made it look like nothing had changed. –  John Keyes Jul 7 '11 at 10:30
My test doesn’t work with option.click(), but it does work with option.select(). In the latest webelement.py source, select has been removed, and click must be used in it’s place. It will be interesting to see if my test works with the latest release. –  John Keyes Jul 7 '11 at 10:58
Accepted solution is VERY SLOW. I recommend @Daniel Abel solution. It would be nice if OP accepted it, it keeps gaining upvotes. –  Peter Masiar Feb 5 at 21:38
possible duplicate of How do I work with dropdowns in Selenium Webdriver? –  Yamikuronue May 6 at 16:30

4 Answers 4

up vote 22 down vote accepted

The easiest way that I have found was to do something along the lines of:

el = driver.find_element_by_id('id_of_select')
for option in el.find_elements_by_tag_name('option'):
    if option.text == 'The Options I Am Looking For':
        option.click() # select() in earlier versions of webdriver

This may have some runtime issues if there are a large number of options, but for us it suffices.

Also this code will work with multi-select

def multiselect_set_selections(driver, element_id, labels):
    el = driver.find_element_by_id(element_id)
    for option in el.find_elements_by_tag_name('option'):
        if option.text in labels:

Then you can transform the following field

# ERROR: Caught exception [ERROR: Unsupported command [addSelection | id=deformField7 | label=ALL]]

Into this call

multiselect_set_selections(driver, 'deformField7', ['ALL'])

Multiple selection errors like the following:

 # ERROR: Caught exception [ERROR: Unsupported command [addSelection | id=deformField5 | label=Apr]]
 # ERROR: Caught exception [ERROR: Unsupported command [addSelection | id=deformField5 | label=Jun]]

Will be fixed with a single call:

multiselect_set_selections(driver, 'deformField5', ['Apr', 'Jun'])
share|improve this answer
I just saw that you had answered your own question, oops :) –  Jason Ward Jul 7 '11 at 13:30
No worries Jason. I tried to answer it myself earlier but six hours have to elapse before I could. I'll give you the kudos anyway :) –  John Keyes Jul 7 '11 at 21:41
@JasonWard How are you iterating over the Web Element object in for loop. I tried the same and got a exception that the object is not iterable. Any suggestion. Thanks –  abhi Apr 18 '13 at 9:53
@abhi Make sure you are using find_elements_by_tag_name and not find_element_by_tag_name (The s in elements matters). –  Jason Ward Jul 24 '13 at 1:43
Good solution, but not as good as Daniel Abel's proposed solution. Better off using the built in Select function –  Chris Bier Mar 27 '14 at 16:04

I think using selenium.webdriver.support.ui.Select is the cleanest way:

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

b = webdriver.Firefox()

# navigate to the page
select = Select(b.find_element_by_id(....))
print select.options
print [o.text for o in select.options] # these are string-s

Using this approach is also the fastest way. I wrote fast_multiselect as analogous function to multiselect_set_selections. On a test with 4 calls to multiselect_set_selections on lists of about 20 items each, the average running time is 16.992 seconds, where fast_multiselect is only 10.441 seconds. Also the latter is much less complicated.

 from selenium.webdriver.support.ui import Select

 def fast_multiselect(driver, element_id, labels):
     select = Select(driver.find_element_by_id(element_id))
     for label in labels:
share|improve this answer
This works and is a good solution. –  Mike Grace Jun 1 '12 at 4:00
Nice. Selenium auto-generated documentation just sucks. –  Stan Sep 27 '12 at 13:07
This is the idiomatic approach. Too bad it isn't the accepted answer. –  Lucas Schwarz Apr 28 at 19:13

I had a similar problem and was able to resolve it by finding the elements by xpath:

from selenium import webdriver
b = webdriver.Firefox()
#...some commands here
b.find_element_by_xpath("//select/option[@value='The Options I am Looking for']").click()
share|improve this answer

Similar to Will's answer, but finds the <select> by its element name, and clicks based on the <option> text.

from selenium import webdriver
b = webdriver.Firefox()
share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.