0

I am struggling to click the first href that matches a keyword. There is at least 2 hrefs that match a keyword im using so selenium fails at clicking the element. I have tried to nominate the class and look inside that class for the Href but the syntax is incorrect. I currently have this code in a try block as it refreshes if the href is not found and tries again.

see below:

<div class="productitem--info">
  <span class="productitem--vendor">
          GlenWyvis</span>
          <h2 class="productitem--title">
        <a href="/collections/new-whisky-arrivals/products/glenwyvis-batch-20-18-2018-vintage-2nd-release" data-product-page-link="">
          GlenWyvis Batch 02/18 | 2nd Release
        </a>
      </h2>

The Python try block I have is below:

while True:
    try:
        element = driver.find_element(By.XPATH, "//*[@class='productitem--title'] and contains(.@href, 'glenwyvis')]")
        element.click()
        break
    except NoSuchElementException:
        driver.refresh()
        time.sleep(3)

Any help is greatly appreciated.

Many thanks.

  • 1
    Please read why a [screenshot of HTML or code or error is a bad idea](https://meta.stackoverflow.com/questions/303812/discourage-screenshots-of-code-and-or-errors). You may like to consider updating the Question with formatted text based relevant HTML, code trials and error stack trace. – undetected Selenium Jul 06 '22 at 22:07
  • 1
    It's not recommended to post code as images. A html sample should be added instead. [How to create a Minimal, Reproducible Example](/help/minimal-reproducible-example) – LMC Jul 06 '22 at 22:07
  • _There is at least 2 hrefs that match a keyword im using_: That's fne but the locator strategy should identify the desired element uniquely. Which element do you want to click? – undetected Selenium Jul 06 '22 at 22:14
  • I wish to click the first or any href that contains the keyword as given, in this case 'glenwyvis'. I am looking to click href="/collections/new-whisky-arrivals/products/glenwyvis-batch-20-18-2018-vintage-2nd-release" . – John Stepehns Jul 06 '22 at 22:19

2 Answers2

1

As per the HTML:

<h2 class="productitem--title">
    <a href="/collections/new-whisky-arrivals/products/glenwyvis-batch-20-18-2018-vintage-2nd-release" data-product-page-link="">
    GlenWyvis Batch 02/18 | 2nd Release
    </a>
</h2>

To click on the element with href starting with /collections/new-whisky-arrivals/products/glenwyvis-batch 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, "h2.productitem--title > a[href^='/collections/new-whisky-arrivals/products/glenwyvis-batch']"))).click()
    
  • Using XPATH:

    WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//h2[@class='productitem--title']/a[starts-with(@href, '/collections/new-whisky-arrivals/products/glenwyvis-batch')]"))).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
  • Thank you, this allowed to me to make this as "//*[@class='productitem--title']/a[contains(@href, 'glenwyvis')]" as I will be changing the keyword from time to time. – John Stepehns Jul 06 '22 at 22:31
  • Hmm :) you need to explain your usecase properly for a canonical answer. At times assumptions fails bluntly ;) – undetected Selenium Jul 06 '22 at 22:33
1

With minimal modifications, you could use

element = driver.find_element(By.XPATH, "//*[@class='productitem--title' and contains(a/@href, 'glenwyvis')]")

This returns the <h2> element with the desired properties.

zx485
  • 28,498
  • 28
  • 50
  • 59