¿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ó.

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


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:


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)

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')


¿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)

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.


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.


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


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()

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)

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);

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)

-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();

}

}


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
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.