1

I have been trying to make a Selenium bot that searches for a word on github, clicks on the first link and then downloads it with Python 3.8 and I got stuck with making the bot click on the hyperlink. I understand that I can make the bot click on it with driver.find_element(By.XPATH, "Xpath").click() but I want to be able to find the path of the href with another method for the sake of learning, in this case CSS_SELECTOR. Source code of the first hyperlink result is like this:

HTML:

source code

Since every single result is under the same "a" selector with a class of "v-align-middle", I thought of using this code: driver.find_element(By.CSS_SELECTOR, ".v-align-middle").click() but it did not seem to work. What am I missing?

undetected Selenium
  • 183,867
  • 41
  • 278
  • 352
KayB
  • 21
  • 4
  • Which [_xpath_](https://stackoverflow.com/a/50882166/7429447) worked for you? – undetected Selenium Mar 18 '22 at 23:16
  • The xpath that worked for me was "//*[@id='js-pjax-container']/div/div[3]/div/ul/li[1]/div[2]/div[1]/div[1]/a" which I gathered from copying the xpath from the part of the source code where href is included. – KayB Mar 18 '22 at 23:35

1 Answers1

1

The desired element is a dynamic element, so to click() on the element 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, "a.v-align-middle[href='/asdf-vm/asdf'][data-hydro-click][data-hydro-click-hmac]"))).click()
    
  • Using XPATH:

    WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//a[@class='v-align-middle' and @href='/asdf-vm/asdf'][@data-hydro-click and @data-hydro-click-hmac]"))).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
    
undetected Selenium
  • 183,867
  • 41
  • 278
  • 352
  • Although you stated that what I want to interact with is dynamic, isn't there a way that I can simply treat it as "the first result to show up" and use no specific code that involves "href='/asdf-vm/asdf'" because the part that comes after href= is going to change for every result. – KayB Mar 18 '22 at 23:44
  • Incase value of `href` attribute is dynamic, then you have to drop the attribute from the [_locator strategies_](https://stackoverflow.com/questions/48054321/of-the-many-findelements-by-functions-in-selenium-when-would-you-use-one-over) – undetected Selenium Mar 18 '22 at 23:46
  • I have just managed to solve it the way I want. It seems that `driver.find_element(By.CSS_SELECTOR, "a.v-align-middle").click()` works with the current version of Selenium instead of the one I was trying. – KayB Mar 19 '22 at 00:03