¿Cómo seleccionar un valor de menú desplegable con Selenium usando Python?

185

Necesito seleccionar un elemento de un menú desplegable.

Por ejemplo:

<select id="fruits01" class="select" name="fruits">
  <option value="0">Choose your fruits:</option>
  <option value="1">Banana</option>
  <option value="2">Mango</option>
</select>

1) Primero tengo que hacer clic en él. Hago esto:

inputElementFruits = driver.find_element_by_xpath("//select[id='fruits']").click()

2) Después de eso tengo que seleccionar el elemento bueno, digamos Mango.

Traté de hacerlo inputElementFruits.send_keys(...)pero no funcionó.

Adam Bovien
fuente

Respuestas:

112

A menos que su clic active algún tipo de llamada ajax para completar su lista, en realidad no necesita ejecutar el clic.

Simplemente encuentre el elemento y luego enumere las opciones, seleccionando las opciones que desee.

Aquí hay un ejemplo:

from selenium import webdriver
b = webdriver.Firefox()
b.find_element_by_xpath("//select[@name='element_name']/option[text()='option_text']").click()

Puede leer más en:
/sqa/1355/unable-to-select-an-option-using-seleniums-python-webdriver

alanning
fuente
18
Para su información, el uso de la Selectclase hace que el problema sea mucho más fácil de resolver, vea la respuesta que publiqué.
alecxe
1
¿Qué hago si estoy usando find_by_id? ¿Cómo proporciono el valor entonces? Además, ¿cómo encuentro el xpathde un elemento?
Prakhar Mohan Srivastava
2
@PrakharMohanSrivastava (y otros) para encontrar el XPath, si tiene la fuente resaltada en las herramientas de desarrollo de Chrome, puede hacer clic derecho en la fuente y elegir Copiar -> XPath para obtener la XPath completa de ese elemento.
mgrollins
¿Y si no tengo el nombre del texto? Solo quiero el primer elemento en el menú.
ScottyBlades
La clase Select vinculada en la respuesta de @ alecxe proporciona una función select_by_index que parece que es lo que desea.
Alanning
321

Selenium proporciona una Selectclase conveniente para trabajar con select -> optionconstrucciones:

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

driver = webdriver.Firefox()
driver.get('url')

select = Select(driver.find_element_by_id('fruits01'))

# select by visible text
select.select_by_visible_text('Banana')

# select by value 
select.select_by_value('1')

Ver también:

alecxe
fuente
55
Este es un gran camino a seguir, y debería ser el método de facto. Sin embargo, notaré que es posible que tenga que usar la versión "xpath" más obtusa si el autor del formulario no ha configurado correctamente un elemento HTML seleccionado. Si simplemente usa campos de entrada, xpath debería funcionar.
Mateo
1
¿podemos encontrar elemento por xpath en lugar de by_id? en la función Seleccionar?
GigaByte
2
Esto no desencadena un evento de entrada para mí :( Tengo que hacerlo yo mismo como se menciona aquí: stackoverflow.com/questions/2856513/…
Frederick Nord
1
Muy agradable. Esto limpió algunos trucos horribles que estaba usando.
jww
25

primero debe importar la clase Select y luego debe crear la instancia de la clase Select. Después de crear la instancia de la clase Select, puede realizar métodos de selección en esa instancia para seleccionar las opciones de la lista desplegable. Aqui esta el codigo

from selenium.webdriver.support.select import Select

select_fr = Select(driver.find_element_by_id("fruits01"))
select_fr.select_by_index(0)
Vaibhav
fuente
13

Espero que este código te ayude.

from selenium.webdriver.support.ui import Select

elemento desplegable con id

ddelement= Select(driver.find_element_by_id('id_of_element'))

elemento desplegable con xpath

ddelement= Select(driver.find_element_by_xpath('xpath_of_element'))

elemento desplegable con selector css

ddelement= Select(driver.find_element_by_css_selector('css_selector_of_element'))

Seleccionar 'Banana' de un menú desplegable

  1. Usando el índice de menú desplegable

ddelement.select_by_index(1)

  1. Usando el valor del menú desplegable

ddelement.select_by_value('1')

  1. Puede usar coincidir con el texto que se muestra en el menú desplegable.

ddelement.select_by_visible_text('Banana')

NaramukAbus
fuente
¿Hay alguna manera de convertirlo en una sola línea de código? en lugar de hacer una variable para luego aplicar Seleccionar? Gracias
Jiraheta
2
puedes escribir un código de línea único como este. Seleccione (driver.find_element_by_id ('id_of_element')). Select_by_index (1)
NaramukAbus
7

Intenté muchas cosas, pero mi menú desplegable estaba dentro de una tabla y no pude realizar una operación de selección simple. Solo la solución a continuación funcionó. Aquí estoy resaltando el elemento desplegable y presionando la flecha hacia abajo hasta obtener el valor deseado

        #identify the drop down element
        elem = browser.find_element_by_name(objectVal)
        for option in elem.find_elements_by_tag_name('option'):
            if option.text == value:
                break

            else:
                ARROW_DOWN = u'\ue015'
                elem.send_keys(ARROW_DOWN)
Abhinav Bhatnagar
fuente
6

No tienes que hacer clic en nada. Use find by xpath o lo que elija y luego use las teclas de envío

Para su ejemplo: HTML:

<select id="fruits01" class="select" name="fruits">
    <option value="0">Choose your fruits:</option>
    <option value="1">Banana</option>
    <option value="2">Mango</option>
</select>

Pitón:

fruit_field = browser.find_element_by_xpath("//input[@name='fruits']")
fruit_field.send_keys("Mango")

Eso es.

Shane Cheek
fuente
3

Puedes usar una combinación de selector css bien

driver.find_element_by_css_selector("#fruits01 [value='1']").click()

Cambie el 1 en el atributo = valor css selector al valor correspondiente con la fruta deseada.

QHarr
fuente
2
from selenium.webdriver.support.ui import Select
driver = webdriver.Ie(".\\IEDriverServer.exe")
driver.get("https://test.com")
select = Select(driver.find_element_by_xpath("""//input[@name='n_name']"""))
select.select_by_index(2)

Funcionará bien

Kuladip
fuente
2

Funciona con el valor de la opción:

from selenium import webdriver
b = webdriver.Firefox()
b.find_element_by_xpath("//select[@class='class_name']/option[@value='option_value']").click()
Jackssn
fuente
2

De esta manera, puede seleccionar todas las opciones en cualquier menú desplegable.

driver.get("https://www.spectrapremium.com/en/aftermarket/north-america")

print( "The title is  : " + driver.title)

inputs = Select(driver.find_element_by_css_selector('#year'))

input1 = len(inputs.options)

for items in range(input1):

    inputs.select_by_index(items)
    time.sleep(1)
Raza ul Mustafa
fuente
Estoy tratando de seleccionar uno por uno usando for items in range(1,input1): inputs.select_by_index(items), pero comienza desde el segundo índice. ¿Cómo puedo obtener el primer valor?
RxT
1

La mejor manera de usar la selenium.webdriver.support.ui.Selectclase para trabajar con la selección desplegable, pero en algún momento no funciona como se esperaba debido a un problema de diseño u otros problemas del HTML.

En este tipo de situación, también puede preferir como solución alternativa utilizando execute_script()lo siguiente:

option_visible_text = "Banana"
select = driver.find_element_by_id("fruits01")

#now use this to select option from dropdown by visible text 
driver.execute_script("var select = arguments[0]; for(var i = 0; i < select.options.length; i++){ if(select.options[i].text == arguments[1]){ select.options[i].selected = true; } }", select, option_visible_text);
Saurabh Gaur
fuente
0

Según el HTML proporcionado:

<select id="fruits01" class="select" name="fruits">
  <option value="0">Choose your fruits:</option>
  <option value="1">Banana</option>
  <option value="2">Mango</option>
</select>

Para seleccionar un <option>elemento de unmenú tienes que usar la clase Seleccionar . Además, como tienes que interactuar con eltienes que inducir WebDriverWait para el element_to_be_clickable().

Para seleccionar el <option>texto con Mango desde elpuede usar cualquiera de las siguientes estrategias de localización :

  • Usando el atributo ID y el select_by_visible_text()método:

    from selenium import webdriver
    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
    
    select = Select(WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.ID, "fruits01"))))
    select.select_by_visible_text("Mango")
  • Usando CSS-SELECTOR y select_by_value()método:

    select = Select(WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "select.select[name='fruits']"))))
    select.select_by_value("2")
  • Usando XPATH y select_by_index()método:

    select = Select(WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "//select[@class='select' and @name='fruits']"))))
    select.select_by_index(2)
DebanjanB
fuente
-2
  1. Elemento de la lista

clase pública ListBoxMultiple {

public static void main(String[] args) throws InterruptedException {
    // TODO Auto-generated method stub
    System.setProperty("webdriver.chrome.driver", "./drivers/chromedriver.exe");
    WebDriver driver=new ChromeDriver();
    driver.get("file:///C:/Users/Amitabh/Desktop/hotel2.html");//open the website
    driver.manage().window().maximize();


    WebElement hotel = driver.findElement(By.id("maarya"));//get the element

    Select sel=new Select(hotel);//for handling list box
    //isMultiple
    if(sel.isMultiple()){
        System.out.println("it is multi select list");
    }
    else{
        System.out.println("it is single select list");
    }
    //select option
    sel.selectByIndex(1);// you can select by index values
    sel.selectByValue("p");//you can select by value
    sel.selectByVisibleText("Fish");// you can also select by visible text of the options
    //deselect option but this is possible only in case of multiple lists
    Thread.sleep(1000);
    sel.deselectByIndex(1);
    sel.deselectAll();

    //getOptions
    List<WebElement> options = sel.getOptions();

    int count=options.size();
    System.out.println("Total options: "+count);

    for(WebElement opt:options){ // getting text of every elements
        String text=opt.getText();
        System.out.println(text);
        }

    //select all options
    for(int i=0;i<count;i++){
        sel.selectByIndex(i);
        Thread.sleep(1000);
    }

    driver.quit();

}

}

amitabh sinha
fuente
2
La pregunta claramente pide una solución de Python, su respuesta es muy apreciada, pero no es necesaria en este contexto, ya que está escrita en Java.
Lo siento, pero esto no es Python como se menciona en la pregunta y en las etiquetas
Laurent