0

I'm trying to select EU Odds from the dropdown in this HTML:

<div id="user-header-r1">
            <div>
                <a class="user-header-fakeselect" onclick="ElementSelect.expand( 'user-header-oddsformat' , 'user-header-oddsformat-expander' )" id="user-header-oddsformat-expander"><span>UK Odds</span></a>
                <ul class="user-header-fakeselect-options hidden" id="user-header-oddsformat">
                    <li><a href="#" onclick="changeOddsFormat(1); return false;"><span>EU Odds</span></a></li>
                    <li><a href="#" onclick="changeOddsFormat(2); return false;"><span>UK Odds</span></a></li>
                    <li><a href="#" onclick="changeOddsFormat(3); return false;"><span>US Odds</span></a></li>
                    <li><a href="#" onclick="changeOddsFormat(4); return false;"><span>HK Odds</span></a></li>
                    <li><a href="#" onclick="changeOddsFormat(5); return false;"><span>MA Odds</span></a></li>
                    <li><a href="#" onclick="changeOddsFormat(6); return false;"><span>IN Odds</span></a></li>

                </ul>
            </div>
            <div><label>Time:</label></div>
            <div>
                <a href="#" class="user-header-fakeselect" onclick="op.showHideTimeZone();ElementSelect.expand( 'user-header-timezone' , 'user-header-timezone-expander' , null , function(){op.hideTimeZone()} );this.blur();return false;" id="user-header-timezone-expander"><span>23 Aug 08:33, GMT +1</span></a>
            </div>


        </div>

I've tried following the answer here with the following code:

target = 'EU Odds'
self.driver.find_element_by_css_selector("user-header-r1 > ul").find_element_by_xpath("./li[.="+target+"]").click()

But I get the following error:

Exception has occurred: NoSuchElementException
Message: no such element: Unable to locate element: {"method":"css selector","selector":"user-header-r1 > ul"}

Where am I going wrong?

2
  • user-header-r1 is an id, not a CSS class, you are trying to find element by CSS selector, which doesn't exist. Try finding by id Commented Aug 23, 2020 at 8:20
  • Thanks. Tried this: self.driver.find_element_by_id("user-header-r1 > ul").find_element_by_xpath("./li[.="+target+"]").click() but got Unable to locate element: {"method":"css selector","selector":"[id="user-header-r1 > ul"]"}. As you can tell I'm really new to scraping so I might need baby steps! Commented Aug 23, 2020 at 8:26

4 Answers 4

1

Your element target having attribute with hidden value:

...<ul class="user-header-fakeselect-options hidden"...

So I think you need trigger from another element first before attack the element target, try following code:

#click this first
self.driver.find_element_by_css_selector('div#user-header-r1 > div > a#user-header-oddsformat-expander > span').click()

target = 'EU Odds'
self.driver.find_element_by_xpath('//ul[@id="user-header-oddsformat"]//span[text()="' +target +'"]').click()
Sign up to request clarification or add additional context in comments.

Comments

1

Expand dropdown and make li elements visible. WebDriverWait will wait for required element conditions, in your the case it's a visibility. To get element by text using xpath you need to use quotas //li[.='Some Text'] in text:

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as ec

driver = webdriver.Chrome()
wait = WebDriverWait(driver, 5)
driver.get("..")

target = "EU Odds"
driver.find_element(By.ID, "user-header-oddsformat-expander").click()
wait.until(ec.element_to_be_clickable((By.XPATH, "//li[.='" + target + "']"))).click()

5 Comments

I get the following error on the last line: Exception has occurred: TypeError 'str' object is not callable
Typo with method arguments. Fixed
Thanks! Ended up using this as I was having issues with the accepted answer. The clickable element was not loading before that snippet tried to click it.
Spoke to soon! Seems to be intermittent - sometimes it selects EU Odds and sometimes it doesn't :( driver.find_element(By.ID, "user-header-oddsformat-expander").click() definitely selects the dropdown. If I step through wait.until(ec.element_to_be_clickable((By.XPATH, "//li[.='" + target + "']"))).click() then it always selects EU Odds. Strange as my understanding of that line is that Selenium is supposed to wait until it can select EU Odds?
MAnaged to get round this by putting a while loop in that checks the right element has been selected or it reruns the selection code. Always manages to get it right after 2-3 attempts but definitely no consistency!
0

To select the element with text as EU Odds you need to induce WebDriverWait for the element_to_be_clickable() and you can use either of the following Locator Strategies:

  • Using CSS_SELECTOR:

    WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "ul#user-header-oddsformat li:first-child>a[onclick^='changeOddsFormat']>span"))).click()
    
  • Using XPATH:

    WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//ul[@id='user-header-oddsformat']//li/a[starts-with(@onclick, 'changeOddsFormat')]/span[text()='EU Odds']"))).click()
    
  • Note : You have to add the following imports :

    from selenium.webdriver.support.ui import WebDriverWait
    from selenium.webdriver.common.by import By
    from selenium.webdriver.support import expected_conditions as EC
    

1 Comment

Both of these time out sadly :(
0

Form the HTML element, the element you are trying to select has an ID named user-header-r1 not a CSS class, try using find_element_by_id('user-header-r1') Then if the element is found, then try using find_element_by_tag_name('ul') on the same search, like so:

head_elem = self.driver.find_element_by_id("user-header-r1")
head_elem.find_element_by_tag_name("ul")

This will first scan the HTML tree for an ID of user-header-r1 which is the first div then finds the ul element inside the div

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.