Atle Røen
Atle Røen

Reputation: 33

How to find combobox and set value using Selenium and find_element_by_xpath

I am trying to set a value in a combobox using selenium. But the find_element_by_xpath statement fails to find the combobox by class or ng-model (in detail I'm trying to change the timeperiod for a stock from one day to one week)

The web page contains the following javascript for the element I'm searching for

**<select ng-model="analysisGraph.periodselector.period" class="ng-valid ng-dirty ng-valid-parse user-success ng-touched">**
    <!-- ngIf: !analysisGraph.periodselector.dayOnly -->
    <option ng-if="!analysisGraph.periodselector.dayOnly" value="INTRADAY" class="ng-binding ng-scope">Intradag</option><!-- end ngIf: !analysisGraph.periodselector.dayOnly --><!-- ngIf: !analysisGraph.periodselector.dayOnly -->
    <option ng-if="!analysisGraph.periodselector.dayOnly" value="ONE_WEEK" class="ng-binding ng-scope">1 uke</option><!-- end ngIf: !analysisGraph.periodselector.dayOnly -->
        <option value="ONE_MONTH" class="ng-binding">1 mnd</option><!-- ngIf: !analysisGraph.periodselector.hideOption.hide3m -->
    <option ng-if="!analysisGraph.periodselector.hideOption.hide3m" value="THREE_MONTHS" class="ng-binding ng-scope">3 mnd</option><!-- end ngIf: !analysisGraph.periodselector.hideOption.hide3m --><!-- ngIf: !analysisGraph.periodselector.hideOption.hide6m -->
    <option ng-if="!analysisGraph.periodselector.hideOption.hide6m" value="SIX_MONTHS" class="ng-binding ng-scope">6 mnd</option><!-- end ngIf: !analysisGraph.periodselector.hideOption.hide6m -->
        <option value="YTD" class="ng-binding">YTD</option><!-- ngIf: !analysisGraph.periodselector.hideOption.hide1y -->
    <option ng-if="!analysisGraph.periodselector.hideOption.hide1y" value="ONE_YEAR" class="ng-binding ng-scope">1 år</option><!-- end ngIf: !analysisGraph.periodselector.hideOption.hide1y --><!-- ngIf: !analysisGraph.periodselector.hideOption.hide3y -->
    <option ng-if="!analysisGraph.periodselector.hideOption.hide3y" value="THREE_YEARS" class="ng-binding ng-scope">3 år</option><!-- end ngIf: !analysisGraph.periodselector.hideOption.hide3y --><!-- ngIf: !analysisGraph.periodselector.hideOption.hide5y -->
    <option ng-if="!analysisGraph.periodselector.hideOption.hide5y" value="FIVE_YEARS" class="ng-binding ng-scope">5 år</option><!-- end ngIf: !analysisGraph.periodselector.hideOption.hide5y --><!-- ngIf: hasLaunchData -->
</select>

I have tried the following code:

from selenium import webdriver
from selenium.webdriver.chrome.options import Options
import time
from bs4 import BeautifulSoup
import pymysql
import ose_data

chrome_options = Options()
driver = webdriver.Chrome(executable_path='chromedriver', options=chrome_options)
driver.get('https://www.oslobors.no/markedsaktivitet/#/details/ADE.OSE/overview')
time.sleep(5)
bs = BeautifulSoup(driver.page_source, 'html.parser')
**driver.find_element_by_xpath("//select[@class='ng-valid ng-dirty ng-valid-parse user-success ng-touched']/option[text()='ONE_WEEK']").click()**

but it fails with the following error:

Error: selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"xpath","selector":"//select[@class='ng-valid ng-dirty ng-valid-parse user-success ng-touched']/option[text()='ONE_WEEK']"} (Session info: chrome=79.0.3945.130)

I also tried searching with driver.find_element_by_xpath("//select[@ng-model='analysisGraph.periodselector.period']/option[text()='ONE_WEEK']").click()

With the same error, anyone see any obious errors from a noob Python programer? :)

Upvotes: 1

Views: 984

Answers (1)

Sers
Sers

Reputation: 12255

Xpath is wrong, use select[ng-model="analysisGraph.periodselector.period"] css selector to get the element. The element is a drop-down with select tag, to select it use Select class. Added WebDriverWait to wait for element to be clickable before interact with it.

from selenium import webdriver
from selenium.webdriver.chrome.options import Options
import time
from bs4 import BeautifulSoup
import pymysql
import ose_data
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.select import Select

chrome_options = Options()
driver = webdriver.Chrome(executable_path='chromedriver', options=chrome_options)
driver.get('https://www.oslobors.no/markedsaktivitet/#/details/ADE.OSE/overview')
wait = WebDriverWait(driver, 10)

# bs = BeautifulSoup(driver.page_source, 'html.parser')
details_period = Select(wait.until(
    EC.element_to_be_clickable((By.CSS_SELECTOR, 'select[ng-model="analysisGraph.periodselector.period"]'))))
details_period.select_by_value('ONE_WEEK')

# You can also use
# details_period.select_by_visible_text()
# details_period.select_by_index()

Upvotes: 1

Related Questions