Search code examples
pythonparsingselenium-webdriverweb

Selenium find_element broke for loop


I find elements with find_elements and after getting child elements with find_element, but the iteration doesn't work further after find_element and the loop stops (although there are several elements found with find_elements)

import os
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait

def getItems(url, xpath):
   path_to_browser = os.path.abspath(os.getcwd()) + "\\driver\\chromedriver"
   service = Service(executable_path=path_to_browser)
   browser = webdriver.Chrome(service=service)
   browser.get(url)
        
   # wait until page is succesfully loaded
   WebDriverWait(browser, 10)

   return browser.find_elements(By.XPATH, xpath)

items = getItems("https://lamoda.ru/c/4153/default-women/?is_sale=1", "/html/body/div[1]/div/main/div/div[2]/div/div[2]/div[2]/div[2]/div")
for idx, item in enumerate(items):
    # only print element with index 0, and stops
    print(idx)
    print(item.find_element(By.XPATH, ".//div/div[1]/div/div[1]/span[2]").text)

Solution

  • Its because this locator return only a single element, so the for loop runs only once, Also i would suggest using stable locators instead of indexed xpaths

    Try below

    import os
    from selenium import webdriver
    from selenium.webdriver.chrome.service import Service
    from selenium.webdriver.common.by import By
    from selenium.webdriver.support.wait import WebDriverWait
    
    
    def getItems(url, xpath):
        path_to_browser = os.path.abspath(os.getcwd()) + "\\driver\\chromedriver"
        service = Service(executable_path=path_to_browser)
        browser = webdriver.Chrome(service=service)
        browser.get(url)
    
        # wait until page is succesfully loaded
        WebDriverWait(browser, 10)
    
        return browser.find_elements(By.XPATH, xpath)
    
    
    items = getItems("https://lamoda.ru/c/4153/default-women/?is_sale=1",
                     '//div[contains(@class,"x-product-card__link")]')
    for idx, item in enumerate(items):
        # only print element with index 0, and stops
        print(idx)
        print(item.find_element(By.XPATH, ".//span[contains(@class,'x-product-card-description__price-new')]").text)
    

    Should print All 60

    0
    849 ₽
    1
    3 890 ₽
    2
    10 990 ₽
    3
    660 ₽
    4
    3 890 ₽
    5
    3 595 ₽
    6
    8 240 ₽
    7
    790 ₽
    8
    57 810 ₽
    9
    5 199 ₽
    10
    5 090 ₽
    11
    1 799 ₽
    ..