Como selecionar um valor de menu suspenso com o Selenium usando Python?

184

Preciso selecionar um elemento em um menu suspenso.

Por exemplo:

<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) Primeiro eu tenho que clicar nele. Eu faço isso:

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

2) Depois disso, tenho que selecionar o elemento bom, digamos Mango.

Tentei fazê-lo, inputElementFruits.send_keys(...)mas não funcionou.

Adam Bovien
fonte

Respostas:

112

A menos que seu clique esteja disparando algum tipo de chamada ajax para preencher sua lista, você não precisará executar o clique.

Basta encontrar o elemento e depois enumerar as opções, selecionando as opções desejadas.

Aqui está um exemplo:

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

Você pode ler mais em:
/sqa/1355/unable-to-select-an-option-using-seleniums-python-webdriver

alanning
fonte
18
Para sua informação, usar Selectclasse torna o problema muito mais fácil de resolver. Veja a resposta que eu postei.
alecxe
1
O que faço se estiver usando find_by_id? Como forneço o valor então? Além disso, como encontro o xpathelemento de?
Prakhar Mohan Srivastava
2
@PrakharMohanSrivastava (e outros) para encontrar o XPath, se você tiver a fonte destacada nas ferramentas de desenvolvimento do Chrome, clique com o botão direito do mouse na fonte e escolha Copiar -> XPath para obter o XPath completo desse elemento.
Mgrollins
E se eu não tiver o nome do texto? Eu só quero o primeiro elemento no menu.
ScottyBlades 16/04
A classe Select vinculada na resposta do @ alecxe fornece uma função select_by_index que parece ser o que você deseja.
alanning 20/04
321

O Selenium fornece uma Selectclasse conveniente para trabalhar com select -> optionconstruções:

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

Veja também:

alecxe
fonte
5
Este é um ótimo caminho a percorrer e deve ser o método de fato. No entanto, observarei que talvez você precise usar a versão mais obtusa do "xpath" se o autor do formulário não tiver configurado corretamente um elemento HTML selecionado. Se simplesmente usar campos de entrada, o xpath deve funcionar.
28517 Matthew
1
podemos encontrar o elemento xpath em vez de by_id? na função Selecionar?
precisa
2
Isso não disparar um evento de entrada para mim :( Eu tenho que fazer isso sozinho como mencionado aqui: stackoverflow.com/questions/2856513/...
Frederick Nord
1
Muito agradável. Isso limpou alguns hacks horríveis que eu estava usando.
jww 16/11/19
25

primeiro, você precisa importar a classe Select e, em seguida, criar a instância da classe Select. Depois de criar a instância da classe Select, você pode executar métodos de seleção nessa instância para selecionar as opções da lista suspensa. Aqui está o código

from selenium.webdriver.support.select import Select

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

Espero que este código o ajude.

from selenium.webdriver.support.ui import Select

elemento suspenso com id

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

elemento suspenso com xpath

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

elemento suspenso com seletor de css

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

Selecionando 'Banana' em uma lista suspensa

  1. Usando o índice de lista suspensa

ddelement.select_by_index(1)

  1. Usando o valor do menu suspenso

ddelement.select_by_value('1')

  1. Você pode usar a correspondência com o texto exibido no menu suspenso.

ddelement.select_by_visible_text('Banana')

NaramukAbus
fonte
Existe uma maneira de transformá-lo em uma única linha de código? em vez de criar uma variável para aplicar o Select? Obrigado
Jiraheta 14/02
2
você pode escrever um único código de linha como este. Selecione (driver.find_element_by_id ('id_of_element')). Select_by_index (1)
NaramukAbus
7

Tentei muitas coisas, mas meu menu suspenso estava dentro de uma tabela e não pude executar uma operação simples de seleção. Somente a solução abaixo funcionou. Aqui estou destacando o elem suspenso e pressionando a seta para baixo até obter o valor desejado -

        #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
fonte
6

Você não precisa clicar em nada. Use find por xpath ou o que você escolher e, em seguida, use as teclas de envio

Para o seu exemplo: 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ão:

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

É isso aí.

Shane Cheek
fonte
3

Você pode usar uma combinação de seletor de css

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

Altere 1 no seletor attribute = value css para o valor correspondente à fruta desejada.

QHarr
fonte
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)

Vai funcionar bem

Kuladip
fonte
2

Funciona com o valor da opção:

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

Dessa forma, você pode selecionar todas as opções em qualquer lista suspensa.

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
fonte
Estou tentando selecionar um por um usando for items in range(1,input1): inputs.select_by_index(items), mas ele começa no segundo índice. Como posso obter o primeiro valor?
RxT 30/06
1

A melhor maneira de usar a selenium.webdriver.support.ui.Selectclasse para trabalhar com a seleção suspensa, mas em algum momento ela não funciona conforme o esperado devido a problemas de design ou outros problemas do HTML.

Nesse tipo de situação, você também pode preferir como solução alternativa usando execute_script()o seguinte: -

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

Conforme o HTML fornecido:

<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 selecionar um <option>elemento de umamenu, você deve usar a classe Select . Além disso, como você precisa interagir com ovocê precisa induzir o WebDriverWait para o element_to_be_clickable().

Para selecionar o <option>com texto como Mango dovocê pode usar, você pode usar uma das seguintes estratégias de localizador :

  • Usando o atributo e método de 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")
  • Usando CSS-SELECTOR e 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 e 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
fonte
-2
  1. Item da lista

classe 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
fonte
2
A pergunta claramente pede uma solução Python, sua resposta é muito apreciada, mas não é necessária nesse contexto, como está escrito em Java.
Desculpe, mas isso não é Python, como mencionado na pergunta e nas tags
Laurent