1

I have the following MRE code that is mean to select EU Odds from a dropdown:

from pathlib import Path from time import sleep from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.support import expected_conditions as ec from selenium.webdriver.support.ui import WebDriverWait chrome_driver = str(Path("chromedriver/chromedriver/")) driver = webdriver.Chrome(chrome_driver) driver.get("https://www.oddsportal.com/matches/tennis/") driver.find_element(By.ID, "user-header-oddsformat-expander").click() sleep(1) wait = WebDriverWait(driver, 10) target = "EU Odds" wait.until(ec.element_to_be_clickable((By.XPATH, "//li[.='" + target + "']"))).click() 

Everything works up until the final line which doesn't make the selection. If I try to do this manually on the page that chromedriver opens then I'm also unable to make the selection. However, if I open up a normal browsing window then I am able to make the selection.

Where am I going wrong?

3
  • 1
    Even if I open the site manually, I can’t make a new selection or some selection other than EU Odds. It always reloads the page with the same option. Are you sure there is nothing wrong with the website itself? Commented Dec 28, 2020 at 16:17
  • @Jarvis - hey. I think you've figured out the issue indirectly. It looks like they've changed the site so you can only change the odds if you're logged in... Commented Dec 28, 2020 at 16:25
  • I see, guess I should have posted this as my answer :D Commented Dec 28, 2020 at 16:26

4 Answers 4

2
+50

The actual issue is with the website itself. Trying to select any other option other than EU Odds doesn’t work even manually. Seems like you need to be logged in to do that.

Sign up to request clarification or add additional context in comments.

1 Comment

I think it’s doing some IP-based filtering and setting up a country based on location. Try with VPN for EU country while running script and that dropdown will default to EU Odds-not the perfect solution but workaround
1

From a broader perspective there is nothing wrong in your code.

However to optimize your code you may like to:

  • Induce WebDriverWait for the element_to_be_clickable() for the expander to be clickable.

  • The texts EU Odds, UK Odds, US Odds, etc are not exactly within the <li> but within it's grand parent //li/a/span

  • So to select EU Odds, UK Odds, US Odds one by one your optimized Locator Strategies can be:

    driver.get('https://www.oddsportal.com/matches/tennis/') WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.ID, "user-header-oddsformat-expander"))).click() target = "EU Odds" WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//li/a/span[text()='" + target + "']"))).click() time.sleep(3) # for visual demonstration WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.ID, "user-header-oddsformat-expander"))).click() target = "UK Odds" WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//li/a/span[text()='" + target + "']"))).click() time.sleep(3) # for visual demonstration WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.ID, "user-header-oddsformat-expander"))).click() target = "US Odds" WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//li/a/span[text()='" + target + "']"))).click() 

This usecase

However even sucessfully clicking on the options with text as EU Odds, UK Odds, US Odds doesn't changes the DOM Tree. Now if you look into the HTML DOM the expander class itself is having the value as user-header-fakeselect-options. Additionally, the onclick attribute of the //li/a/span items are having return false;.

fakeselect

As per the discussion What's the effect of adding 'return false' to a click event listener? return false; does three separate things when called:

  • Calls event.preventDefault();
  • Calls event.stopPropagation();
  • Stops callback execution and returns immediately when called.

Hence selecting either of the dropdown options doesn't fires the onclick event and the HTML DOM remains unchanged.


Conclusion

Possibly the DOM would change as per the onclick events when a authenticated user performs the selection after loggind in within the website.

Comments

0

Try this. Selenium has a special way to handle dropdown selection

First import select :

from selenium.webdriver.support.ui import Select 

Then assign the dropdown to a variable:

dropdown_element = browser.find_element_by_xpath('//*[@id="exam_id"]') 

Then create an object:

dropdown_object = Select(dropdown_element) 

Finally select the option:(there will be a value for every options)

dropdown_object.select_by_value('17') 

4 Comments

Thanks for trying to help out! I'm not sure what element I should be searching for in this line; browser.find_element_by_xpath(<what goes here?>). I've tried '//*[@id="user-header-oddsformat-expander"]' which was what I clicked on before but I get the following error: Select only works on <select> elements, not on <a>. I can't find a <select> element in the HTML for the dropdown?
Can you add a screenshot of the website to your question and highlight the dropdown
Hi. The website address is https://www.oddsportal.com/matches/tennis/
Just to add to this. Selenium clicks on the dropdown successfully using this line: driver.find_element(By.ID, "user-header-oddsformat-expander").click()
0

There are two issues with the xpatי: Too many apostrophes around the text Trying to locate the wrong tag, the clickable element is the <a> tag, not the <li> tag.

Use "//a[.=' + target + ']"

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.