0

I'm trying to get all the elements with bg-primary class and save their href (hyperlink) value in a variable. Here is my code:

elems = driver.find_elements(By.CLASS_NAME , "bg-primary")
    
    for elem in elems:
        if (elem.get_attribute("href")):
            print(elem.get_attribute("href"))

And this is the website's code which has class: "bg-primary" I'm trying to search for it yet I'm not getting any results.

That's what I tried. This code block is dynamically activated on the site and I have WebDriverWait elements for waiting on the element to appear.

2 Answers2

0

If the elements with the "bg-primary" class are dynamically activated on the site, you might face a timing issue where the elements are unavailable when you try to find them using Selenium. To resolve this, you can use WebDriverWait to wait for the elements to become visible before retrieving their href values. Here's how you can modify your code:

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

# Wait for the elements with "bg-primary" class to become visible
elems = WebDriverWait(driver, 10).until(EC.visibility_of_all_elements_located((By.CLASS_NAME, "bg-primary")))

for elem in elems:
    if elem.get_attribute("href"):
        print(elem.get_attribute("href"))

By using WebDriverWait with EC.visibility_of_all_elements_located, the code will wait for up to 10 seconds for the elements with the "bg-primary" class to become visible on the page before attempting to retrieve their href values. This should ensure that you get all the elements you are looking for. If the elements are still not selected, you might need to adjust the waiting time or use different expected conditions based on the behavior of the website.

Kayvan Shah
  • 375
  • 2
  • 11
  • elems = WebDriverWait(driver, 10).until(EC.visibility_of_all_elements_located((By.CLASS_NAME, "bg-primary"))) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib/python3/dist-packages/selenium/webdriver/support/wait.py", line 95, in until raise TimeoutException(message, screen, stacktrace) selenium.common.exceptions.TimeoutException: Message: (no message) Could it be that the driver itself changes at some point when interacting with elements (without leaving the page) and that might be messing with it? – Mihajlo Spasic Jul 29 '23 at 11:13
  • Try increasing the timeout or check for encoded sessions of the website. – Kayvan Shah Aug 04 '23 at 05:39
  • What's an encoded session of the website? Are you referring to HTTP session tracking (that's the first thing that pops up after searching)? – Mihajlo Spasic Aug 07 '23 at 20:50
  • Yes, I am talking about the same. Some websites have session strings attached to the URL you hit. – Kayvan Shah Aug 08 '23 at 00:43
0

Given the HTML:

html

you have to make a few adjustments as follows:

  • The class attribute of the <a> element contains multiple values and bg-primary is one of them.
  • Additionally the elements looks to be dynamic element.

Solution

To extract all the elements with bg-primary class and save their href value you have to induce WebDriverWait for visibility_of_all_elements_located() and you can use either of the following locator strategies:

  • Using CSS_SELECTOR:

    print([my_elem.get_attribute("href") for my_elem in WebDriverWait(driver, 20).until(EC.visibility_of_all_elements_located((By.CSS_SELECTOR, "a.bg-primary")))])
    
  • Using XPATH:

    print([my_elem.get_attribute("href") for my_elem in WebDriverWait(driver, 20).until(EC.visibility_of_all_elements_located((By.XPATH, "//a[contains(@class, 'bg-primary')]")))])
    
  • 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
  • print([my_elem.get_attribute("href") for my_elem in WebDriverWait(driver, 20).until(EC.visibility_of_all_elements_located((By.CSS_SELECTOR, "a.bg-primary")))]) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib/python3/dist-packages/selenium/webdriver/support/wait.py", line 95, in until raise TimeoutException(message, screen, stacktrace) selenium.common.exceptions.TimeoutException: Message: (no message) Error says timeout so it didn't find it at all – Mihajlo Spasic Jul 29 '23 at 11:16
  • I feel like there is a chance for a whole driver to change when I load the element. Could that be an issue even when I'm not leaving the website? – Mihajlo Spasic Jul 29 '23 at 11:17