Jak wybrać wartość menu rozwijanego za pomocą Selenium przy użyciu Pythona?

185

Muszę wybrać element z menu rozwijanego .

Na przykład:

<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) Najpierw muszę go kliknąć. Robię to:

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

2) Następnie muszę wybrać, powiedzmy, dobry element Mango.

Próbowałem to zrobić, inputElementFruits.send_keys(...)ale nie udało się.

Adam Bovien
źródło

Odpowiedzi:

112

O ile twoje kliknięcie nie uruchamia jakiegoś rodzaju wywołania Ajax w celu wypełnienia listy, tak naprawdę nie musisz wykonywać kliknięcia.

Po prostu znajdź element, a następnie wylicz opcje, wybierając żądane opcje.

Oto przykład:

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

Możesz przeczytać więcej na:
/sqa/1355/unable-to-select-an-option-using-seleniums-python-webdriver

alanning
źródło
18
FYI, użycie Selectklasy znacznie ułatwia rozwiązanie problemu, zobacz odpowiedź, którą opublikowałem.
alecxe
1
Co mam zrobić, jeśli używam find_by_id? Jak więc podać wartość? Ponadto, jak znaleźć xpathelement?
Prakhar Mohan Srivastava
2
@PrakharMohanSrivastava (i inne), aby znaleźć XPath, jeśli masz zaznaczone źródło w narzędziach programistycznych Chrome, możesz kliknąć je prawym przyciskiem myszy i wybrać Kopiuj -> XPath, aby uzyskać pełną XPath tego elementu.
mgrollins
A co jeśli nie mam nazwy tekstu? Chcę tylko pierwszego elementu w menu.
ScottyBlades
Klasa Select połączona w odpowiedzi @ alecxe udostępnia funkcję select_by_index, która wydaje się być tym, czego chcesz.
alanning
321

Selenium zapewnia wygodną Selectklasę do pracy z select -> optionkonstrukcjami:

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

Zobacz też:

alecxe
źródło
5
To świetna droga i powinna być metodą de facto. Jednak zauważę, że może być konieczne użycie bardziej rozwlekłej wersji „xpath”, jeśli autor formularza nie skonfigurował poprawnie wybranego elementu HTML. Jeśli po prostu używasz pól wejściowych, xpath powinien działać.
Matthew
1
czy możemy znaleźć element według xpath zamiast by_id? w funkcji Wybierz?
GigaByte
2
To nie wyzwala dla mnie zdarzenia wejściowego :( Muszę to zrobić sam, jak wspomniano tutaj: stackoverflow.com/questions/2856513/…
Frederick Nord
1
Bardzo dobrze. To wyczyściło niektóre okropne hacki, których używałem.
jww
25

najpierw należy zaimportować klasę Select, a następnie utworzyć instancję klasy Select. Po utworzeniu instancji klasy Select można wykonać metody wyboru na tej instancji, aby wybrać opcje z listy rozwijanej. Oto kod

from selenium.webdriver.support.select import Select

select_fr = Select(driver.find_element_by_id("fruits01"))
select_fr.select_by_index(0)
Vaibhav
źródło
13

Mam nadzieję, że ten kod Ci pomoże.

from selenium.webdriver.support.ui import Select

element listy rozwijanej z identyfikatorem

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

element rozwijany z xpath

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

element listy rozwijanej z selektorem css

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

Wybierając „Banan” z menu

  1. Korzystanie z indeksu listy rozwijanej

ddelement.select_by_index(1)

  1. Korzystanie z listy rozwijanej

ddelement.select_by_value('1')

  1. Możesz użyć dopasowania do tekstu, który jest wyświetlany na liście rozwijanej.

ddelement.select_by_visible_text('Banana')

NaramukAbus
źródło
Czy istnieje sposób, aby zrobić to w pojedynczej linii kodu? zamiast tworzyć zmienną, aby następnie zastosować Wybierz? Dzięki
Jiraheta,
2
możesz napisać taki jednoliniowy kod. Wybierz (driver.find_element_by_id ('id_of_element')). Select_by_index (1)
NaramukAbus
7

Próbowałem wielu rzeczy, ale menu rozwijane znajdowało się wewnątrz tabeli i nie byłem w stanie wykonać prostej operacji wyboru. Działało tylko poniższe rozwiązanie. Tutaj podświetlam rozwijany element i naciskam strzałkę w dół, aż uzyskam żądaną wartość -

        #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
źródło
6

Nie musisz nic klikać. Użyj funkcji znajdź według xpath lub cokolwiek innego, a następnie użyj kluczy wysyłania

Na przykład: 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>

Pyton:

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

Otóż ​​to.

Shane Cheek
źródło
3

Możesz użyć kombinacji selektora CSS

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

Zmień 1 w selektorze atrybut = wartość css na wartość odpowiadającą żądanemu owocowi.

QHarr
źródło
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)

Będzie działać dobrze

Kuladip
źródło
2

Działa z wartością opcji:

from selenium import webdriver
b = webdriver.Firefox()
b.find_element_by_xpath("//select[@class='class_name']/option[@value='option_value']").click()
Jackssn
źródło
2

W ten sposób możesz wybrać wszystkie opcje z dowolnych list rozwijanych.

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
źródło
Próbuję wybierać jeden po drugim za pomocą for items in range(1,input1): inputs.select_by_index(items), ale zaczyna się od drugiego indeksu. Jak mogę uzyskać pierwszą wartość?
RxT
1

Najlepszy sposób na użycie selenium.webdriver.support.ui.Selectklasy do pracy z wyborem rozwijanym, ale czasami nie działa zgodnie z oczekiwaniami z powodu problemów projektowych lub innych problemów z HTML.

W tego typu sytuacji możesz również preferować alternatywne rozwiązanie, używając execute_script()jak poniżej: -

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
źródło
0

Zgodnie z dostarczonym kodem 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>

Aby wybrać <option>element z plikumusisz użyć Select Class . Ponadto, ponieważ musisz wejść w interakcję zmusisz wywołać WebDriverWait for the element_to_be_clickable().

Aby wybrać <option>z tekstem jako Mango zmożesz użyć, możesz użyć jednej z następujących strategii lokalizacji :

  • Korzystanie z atrybutu i metody 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")
  • Używając CSS-SELECTOR i select_by_value()metody:

    select = Select(WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "select.select[name='fruits']"))))
    select.select_by_value("2")
  • Korzystanie z XPATH i select_by_index()metody:

    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
źródło
-2
  1. Element listy

public class 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
źródło
2
Pytanie wyraźnie dotyczy rozwiązania w Pythonie, twoja odpowiedź jest bardzo ceniona, ale nie jest wymagana w tym kontekście, ponieważ jest napisana w Javie.
Przepraszamy, ale to nie jest Python, jak wspomniano w pytaniu i w tagach
Laurent,