Search code examples
pythonseleniumloopssequential-workflow

Making steps in a for loop sequential when using Python and Selenium


I'm trying to loop through a list of links on a webpage, clicking on each using selenium, then copying a tinylink from each page before finally returning to the master list page. So far it will access the page, but I'm struggling to get the sequentiality of

click link-> load page-> click 'share'-> click 'copy'

Currently it's accessing the master list page and going straight to clicking 'share' before clicking into the first link. Maybe I'm overthinking this, as I thought sleep(1) would cut the program there until the next step. Please help!

#below accesses each link, opens the tinylink, and copies it
powerforms = driver.find_element_by_xpath("//*[@id='main-content']/ul")
links = powerforms.find_elements_by_tag_name("li")

for link in links:
    link.click()
    sleep(1)

    #clicks 'Share' button to open popout
    share = driver.find_element_by_id("shareContentLink")
    share.click()
    sleep(1)

    #clicks 'Copy' button to copy the tinylink to the clipboard
    copy = driver.find_element_by_id("share-link-copy-button")
    copy.click()
    sleep(1)
    break

Solution

  • Instead of sleep, you should use WebDriverWait, to be sure the element is present on the page, is loaded and interactive. Sleep doesn't take into consideration your internet speed etc.

    from selenium import webdriver
    from selenium.webdriver.support.ui import WebDriverWait
    from selenium.webdriver.support import expected_conditions as EC
    from selenium.webdriver.common.by import By
    from selenium.common.exceptions import TimeoutException
    
    driver = webdriver.Firefox()
    driver.get(url)
    max_wait_time = 10 #seconds
    
    powerforms = driver.find_element_by_xpath("//*[@id='main-content']/ul")
    links = powerforms.find_elements_by_tag_name("li")
    
    for link in links:
        try:
            link = WebDriverWait(driver, max_wait_time).until(EC.presence_of_element_located(link))
            link.click()
    
            # clicks 'Share' button to open popout
            share = WebDriverWait(driver, max_wait_time).until(EC.presence_of_element_located((By.ID, 'shareContentLink')))
            share.click()
            # sleep(1)
    
            # clicks 'Copy' button to copy the tinylink to the clipboard
            copy = WebDriverWait(driver, max_wait_time).until(EC.presence_of_element_located((By.ID, 'share-link-copy-button')))
            copy.click()
            # sleep(1)
    
        except TimeoutException:
            print("Couldn't load element")
            continue