Come selezionare un valore di menu a discesa con Selenium usando Python?


185

Devo selezionare un elemento da un menu a discesa.

Per esempio:

<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) Prima devo fare clic su di esso. Lo faccio:

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

2) Dopodiché devo selezionare l'elemento buono, diciamo Mango.

Ho provato a farlo con inputElementFruits.send_keys(...)ma non ha funzionato.

Risposte:


113

A meno che il tuo clic non generi una sorta di chiamata Ajax per popolare il tuo elenco, in realtà non è necessario eseguire il clic.

Basta trovare l'elemento e quindi enumerare le opzioni, selezionando le opzioni desiderate.

Ecco un esempio:

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

Puoi leggere di più in:
/sqa/1355/unable-to-select-an-option-using-seleniums-python-webdriver


18
Cordiali saluti, l'utilizzo della Selectclasse rende il problema molto più facile da risolvere, vedere la risposta che ho pubblicato.
alecxe,

1
Cosa devo fare se sto usando find_by_id? Come posso fornire il valore quindi? Inoltre, come posso trovare l' xpathelemento di un elemento?
Prakhar Mohan Srivastava,

2
@PrakharMohanSrivastava (e altri) per trovare XPath, se hai la fonte evidenziata negli strumenti di sviluppo di Chrome, puoi fare clic con il tasto destro del mouse sulla fonte e scegliere Copia -> XPath per ottenere l'XPath completo di quell'elemento.
mgrollins,

E se non avessi il nome del testo? Voglio solo il primo elemento nel menu.
ScottyBlades

La classe Select collegata nella risposta di @ alecxe fornisce una funzione select_by_index che sembra essere ciò che desideri.
alanning il

322

Il selenio offre una Selectclasse conveniente per lavorare con select -> optioncostrutti:

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

Guarda anche:


5
Questo è un ottimo modo di procedere e dovrebbe essere il metodo di fatto. Tuttavia, noterò che potrebbe essere necessario utilizzare la versione "xpath" più ottusa se l'autore del modulo non ha impostato correttamente un elemento HTML selezionato. Se si utilizzano semplicemente i campi di input, xpath dovrebbe funzionare.
Matteo,

1
possiamo trovare element per xpath anziché by_id? in Seleziona funzione?
GigaByte,

2
Questo non attiva un evento di input per me :( Devo farlo da solo, come indicato qui: stackoverflow.com/questions/2856513/…
Frederick Nord

1
Molto bella. Questo ha ripulito alcuni terribili hack che stavo usando.
19-19

25

in primo luogo è necessario importare la classe Select e quindi è necessario creare l'istanza della classe Select. Dopo aver creato l'istanza della classe Select, è possibile eseguire i metodi di selezione su quell'istanza per selezionare le opzioni dall'elenco a discesa. Ecco il codice

from selenium.webdriver.support.select import Select

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

14

Spero che questo codice ti possa aiutare.

from selenium.webdriver.support.ui import Select

elemento a discesa con ID

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

elemento a discesa con xpath

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

elemento a discesa con selettore css

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

Selezionando "Banana" da un menu a discesa

  1. Utilizzando l'indice del menu a discesa

ddelement.select_by_index(1)

  1. Utilizzando il valore del menu a discesa

ddelement.select_by_value('1')

  1. È possibile utilizzare la corrispondenza con il testo visualizzato nel menu a discesa.

ddelement.select_by_visible_text('Banana')


C'è un modo per trasformarlo in una singola riga di codice? piuttosto che creare una variabile per applicare quindi Seleziona? Grazie
Jiraheta,

2
puoi scrivere un codice a riga singola come questo. Seleziona (driver.find_element_by_id ('id_of_element')). Select_by_index (1)
NaramukAbus

7

Ho provato molte cose, ma il mio menu a discesa era all'interno di un tavolo e non ero in grado di eseguire una semplice operazione di selezione. Funzionava solo la soluzione seguente. Qui sto evidenziando il menu a discesa elem e premendo la freccia verso il basso fino a ottenere il valore desiderato -

        #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

Non devi fare clic su nulla. Usa find by xpath o qualunque cosa tu scelga e quindi usa i tasti di invio

Per il tuo esempio: 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>

Pitone:

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

Questo è tutto.


3

Puoi usare bene una combinazione di selettori css

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

Modificare 1 nel selettore attributo = valore css nel valore corrispondente al frutto desiderato.


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

Funzionerà benissimo


1

Funziona con il valore dell'opzione:

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

1

In questo modo puoi selezionare tutte le opzioni in qualsiasi menu a discesa.

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)

Sto provando a selezionare uno per uno usando for items in range(1,input1): inputs.select_by_index(items), ma inizia dal secondo indice. Come posso ottenere il primo valore?
RxT

1

Come da HTML fornito:

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

Per selezionare un <option>elemento da amenu devi usare Seleziona classe . Inoltre, poiché devi interagire condevi indurre WebDriverWait per il element_to_be_clickable().

Per selezionare il <option>testo con Mango dalpuoi usare puoi usare una delle seguenti strategie di localizzazione :

  • Utilizzando l' attributo ID e il select_by_visible_text()metodo:

    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")
  • Utilizzando CSS-SELECTOR e select_by_value()metodo:

    select = Select(WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "select.select[name='fruits']"))))
    select.select_by_value("2")
  • Utilizzando XPATH e select_by_index()metodo:

    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)

0

Il modo migliore per utilizzare la selenium.webdriver.support.ui.Selectclasse per lavorare con la selezione a discesa, ma a volte non funziona come previsto a causa di problemi di progettazione o altri problemi dell'HTML.

In questo tipo di situazione puoi anche preferire come soluzione alternativa usando execute_script()come di seguito: -

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

-2
  1. Voce di elenco

listBoxMultiple di classe pubblica {

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 domanda richiede chiaramente una soluzione Python, la tua risposta è molto apprezzata, ma non è richiesta in questo contesto poiché è scritta in Java.

Ci dispiace ma questo non è Python come menzionato nella domanda e nei tag
Laurent,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.