Comment sélectionner une valeur de menu déroulant avec Selenium en utilisant Python?


185

J'ai besoin de sélectionner un élément dans un menu déroulant.

Par exemple:

<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) Je dois d'abord cliquer dessus. Je fais ça:

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

2) Après cela, je dois sélectionner le bon élément, disons Mango.

J'ai essayé de le faire avec inputElementFruits.send_keys(...)mais cela n'a pas fonctionné.

Réponses:


112

À moins que votre clic ne déclenche une sorte d'appel ajax pour remplir votre liste, vous n'avez pas réellement besoin d'exécuter le clic.

Trouvez simplement l'élément, puis énumérez les options, en sélectionnant les options souhaitées.

Voici un exemple:

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

Vous pouvez en savoir plus sur:
/sqa/1355/unable-to-select-an-option-using-seleniums-python-webdriver


18
Pour info, l'utilisation de la Selectclasse rend le problème beaucoup plus facile à résoudre, voir la réponse que j'ai publiée.
alecxe

1
Que dois-je faire si j'utilise find_by_id? Comment puis-je fournir la valeur alors? Aussi, comment trouver le xpathd'un élément?
Prakhar Mohan Srivastava

2
@PrakharMohanSrivastava (et autres) pour trouver le XPath, si vous avez la source en surbrillance dans les outils de développement Chrome, vous pouvez faire un clic droit sur la source et choisir Copier -> XPath pour obtenir le XPath complet de cet élément.
mgrollins

Et si je n'ai pas le nom du texte? Je veux juste le premier élément du menu.
ScottyBlades

La classe Select liée dans la réponse de @ alecxe fournit une fonction select_by_index qui semble être ce que vous voulez.
alanning

321

Selenium fournit une Selectclasse pratique pour travailler avec des select -> optionconstructions:

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

Voir également:


5
C'est une excellente façon de procéder et devrait être la méthode de facto. Cependant, je noterai que vous devrez peut-être utiliser la version "xpath" plus obtuse si l'auteur du formulaire n'a pas correctement configuré un élément HTML sélectionné. Si vous utilisez simplement des champs de saisie, xpath devrait fonctionner.
Matthew

1
pouvons-nous trouver un élément par xpath au lieu de by_id? dans Sélectionner la fonction?
GigaByte

2
Cela ne déclenche pas d'événement d'entrée pour moi: (Je dois le faire moi-même comme mentionné ici: stackoverflow.com/questions/2856513/…
Frederick Nord

1
Très agréable. Cela a nettoyé quelques horribles hacks que j'utilisais.
jww

25

Tout d'abord, vous devez importer la classe Select, puis vous devez créer l'instance de la classe Select. Après avoir créé l'instance de la classe Select, vous pouvez exécuter des méthodes de sélection sur cette instance pour sélectionner les options dans la liste déroulante. Voici le code

from selenium.webdriver.support.select import Select

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

13

J'espère que ce code vous aidera.

from selenium.webdriver.support.ui import Select

élément déroulant avec identifiant

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

élément dropdown avec xpath

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

Élément déroulant avec sélecteur css

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

Sélectionner 'Banana' dans une liste déroulante

  1. Utilisation de l'index de la liste déroulante

ddelement.select_by_index(1)

  1. Utilisation de la valeur de dropdown

ddelement.select_by_value('1')

  1. Vous pouvez utiliser faire correspondre le texte affiché dans la liste déroulante.

ddelement.select_by_visible_text('Banana')


Existe-t-il un moyen d'en faire une seule ligne de code? plutôt que de créer une variable pour ensuite appliquer la sélection? Merci
Jiraheta le

2
vous pouvez écrire un code sur une seule ligne comme celui-ci. Select (driver.find_element_by_id ('id_of_element')). Select_by_index (1)
NaramukAbus

7

J'ai essayé beaucoup de choses, mais mon menu déroulant était à l'intérieur d'une table et je n'ai pas pu effectuer une simple opération de sélection. Seule la solution ci-dessous a fonctionné. Ici, je mets en évidence un élément déroulant et j'appuie sur la flèche vers le bas jusqu'à obtenir la valeur souhaitée -

        #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

Vous n'êtes pas obligé de cliquer sur quoi que ce soit. Utilisez find by xpath ou ce que vous choisissez, puis utilisez les touches d'envoi

Pour votre exemple: 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>

Python:

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

C'est tout.


3

Vous pouvez utiliser une combinaison de sélecteurs CSS dans un puits

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

Remplacez le 1 dans le sélecteur attribut = valeur par la valeur correspondant au fruit souhaité.


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)

Cela fonctionnera bien


2

Cela fonctionne avec la valeur de l'option:

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

2

De cette façon, vous pouvez sélectionner toutes les options dans n'importe quelle liste déroulante.

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)

J'essaie de sélectionner un par un en utilisant for items in range(1,input1): inputs.select_by_index(items), mais cela commence à partir du deuxième index. Comment puis-je obtenir la première valeur?
RxT

1

La meilleure façon d'utiliser la selenium.webdriver.support.ui.Selectclasse pour travailler avec la sélection déroulante, mais parfois cela ne fonctionne pas comme prévu en raison d'un problème de conception ou d'autres problèmes de HTML.

Dans ce type de situation, vous pouvez également préférer une solution alternative en utilisant execute_script()comme ci-dessous: -

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

Selon le HTML fourni:

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

Pour sélectionner un <option>élément dans unvous devez utiliser le menu Sélectionner une classe . De plus, comme vous devez interagir avec levous devez induire WebDriverWait pour le element_to_be_clickable().

Pour sélectionner le <option>avec le texte comme Mango dans levous pouvez utiliser vous pouvez utiliser l'une des stratégies de localisation suivantes :

  • Utilisation de l' attribut et de la méthode IDselect_by_visible_text() :

    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")
  • Utilisation de CSS-SELECTOR et de la select_by_value()méthode:

    select = Select(WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "select.select[name='fruits']"))))
    select.select_by_value("2")
  • Utilisation de XPATH et de la select_by_index()méthode:

    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. Élément de liste

classe publique 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 question demande clairement une solution Python, votre réponse est très appréciée, mais n'est pas requise dans ce contexte car elle est écrite en Java.

Désolé mais ce n'est pas Python comme mentionné dans la question et dans les tags
Laurent
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.