1

I have a dropdown element, I want to select the All option, the corresponding HTML code is:

<div class="dataTables_length" id="indicators_length"> 
  <label>
    <span class="result-mune">
      <span>Results </span>per page:
    </span> 
    <select name="indicators_length" aria-controls="indicators" class="jcf-hidden">
      <option value="25">25</option>
      <option value="50">50</option>
      <option value="100">100</option>
      <option value="200">200</option>
      <option value="-1">All</option>
    </select>
    <span class="jcf-select jcf-unselectable">
      <span class="jcf-select-text">
        <span class="">25</span>
      </span>
      <span class="jcf-select-opener"></span>
    </span>
  </label>
</div>

the select element is not highlighted using the browser Inspect method, looks like this drop down is triggered by js. I tried to use the Select class described here:

select = Select(self._wait.until(EC.presence_of_element_located_by((By.XPATH, "//div[@id = 'indicators_length']//select[@name = 'indicators_length']")))
select.select_by_value('-1')

not working. and ActionChain method and even execute_script method, all not working. This bothers me a lot, hope somebody can help.

LuKa Chen
  • 33
  • 1
  • 6

3 Answers3

1

you don't really need to select the option just click the span and it will set the option automatically.

driver = webdriver.Chrome()
driver.get("......")

# click "OK, I Agree" cookies
driver.find_element_by_css_selector('.agree-button.eu-cookie-compliance-default-button').click()
# scroll down to make dropdown option visible
driver.find_element_by_css_selector('h4.pane-title').location_once_scrolled_into_view

select = driver.find_element_by_xpath('//span[@class="result-mune"]/following-sibling::span')
select.click()
# wait until javascript generate fake option element because it actually span
time.sleep(1)
select.find_element_by_css_selector('ul li span[data-index="4"]').click()
ewwink
  • 18,382
  • 2
  • 44
  • 54
  • 1
    thanks @ewwink, I will mark this as the right answer. It worked. I think the problem is selenium actions are performed based on the current webpage view point instead of the DOM, that's why `.location_once_scrolled_into_view` is needed, am I right? – LuKa Chen Dec 03 '18 at 14:07
0

try this one:

driver.execute_script('document.getElementsByName("indicators_length")[0].value = 50;

If its created and loaded after page load make sure you add some sleep to let it render;

Tom St
  • 908
  • 8
  • 15
  • thanks bro, I tried this, nothing happened. `self._browser.implicitly_wait(5) self._browser.execute_script('document.getElementsByName("qs-rankings-indicators_length")[0].value = 500;')` – LuKa Chen Dec 03 '18 at 12:53
  • try using just python's normal time.sleep, if that wont help, it might not you can try running js via timeout (though its hardcoded) - so driver.execute_script('setTimeout(function() { document.getElementsByName("qs-rankings-indicators_length")[0].value = 500;}, 2000);') – Tom St Dec 04 '18 at 23:00
  • another important thing... oonce the driver opens chrome/firefox (requiring testing with real browser and not headless), then ctrl+shift+c to open console, just paste your javascript and enter - i found this to be great way for testing/debugging :) – Tom St Dec 04 '18 at 23:02
  • Nice tips, thanks bro. It turns out the problem is due to unexpected popups in this dynamics website, and if the target element is not visible in the current page view and there is no element to respond the action at the coordinate, then the action is omitted. But if there is other element, then throw `Other element would receive the action` exception – LuKa Chen Dec 05 '18 at 01:46
0

I tried using the Selenium Select class, it can find the element but it cannot select an option from the element. Not sure whats going on, could be the class "jcf-hidden" on the element.

Having said that, I took a stab at it and below is my approach. Try it out, it worked on my system, you have to handle the clicking of "OK, I Agree" button click, I did that manually.

import time
from selenium.webdriver import Chrome

driver = Chrome()
driver.get('https://www.topuniversities.com/university-rankings/world-university-rankings/2019')

# Remove this nasty time.sleep and implement webdriver wait
# Handle the OK, I Agree
time.sleep(5)
i_agree = driver.find_element_by_css_selector('button[class*="eu-cookie-compliance-default-button"]')
i_agree.click()


time.sleep(5)
# Open the Select
rankings_length = driver.find_element_by_id('qs-rankings_length')
select_opener = rankings_length.find_element_by_class_name('jcf-select-opener')
select_opener.click()

# loop through the list
select_content = rankings_length.find_element_by_class_name('jcf-list-content')
for content in select_content.find_elements_by_tag_name('li'):
    if content.text == 'All':
        content.click()
Satish
  • 1,976
  • 1
  • 15
  • 19
  • thanks @Satish, but I got this error, `selenium.common.exceptions.WebDriverException: Message: unknown error: Element is not clickable at point (1107, 910). Other element would receive the click:
    ...
    `
    – LuKa Chen Dec 03 '18 at 14:13
  • It is because you have to click the I Agree button, as I stated, I manually clicked it. Now the code is updated to click that button before finding the select opener – Satish Dec 03 '18 at 16:09
  • "Ok, I Agree" is not belong to `sliding-popup-bottom` class. I figured out how the problem comes anyway, thanks for help. – LuKa Chen Dec 05 '18 at 01:34
  • Glad to help. If my answer helped to solve your problem. Give it an upvote – Satish Dec 05 '18 at 01:41