首页 > 解决方案 > Selenium - 为什么 NoSuchElementException 在第二次 for 循环迭代中发生?

问题描述

我正在尝试遍历与 div 标签匹配的 Web 元素列表。第一个循环运行良好,但第二个循环抛出一个NoSuchElementException. 这是我的代码的最小示例:

for div in driver.find_elements_by_xpath("//div[@class='class_name']"):
    print(div.text)
    print(f"Current url 1: {driver.current_url}") # url 
    new_url = url + "/page/"
    time.sleep(2)
    driver.get(new_url)
    print(f"Current url 2: {driver.current_url}") # new_url
    time.sleep(2)
    # Then get info from the new url

    # Go back
    # driver.execute_script("window.history.go(-1)")
    driver.back()
    print(f"Current url 3: {driver.current_url}") # url
    print("Sleeping for 3 seconds from now...")
    time.sleep(3)

谢谢!

标签: pythonseleniumweb-scrapingnosuchelementexception

解决方案


您得到StaleElementReferenceException的原因是对您尝试使用的 Web 元素的引用不再是有效的 AKA 陈旧。
请参阅此处或有关过时元素引用异常的任何其他资源。
由于您访问了其他网页,即使您回到初始网页,您获得的所有网页元素都会变成陈旧的元素。
要克服这个问题,您必须再次获得这些元素。
因此,我建议您使用以下代码,而不是您当前的代码:

divs = driver.find_elements_by_xpath("//div[@class='class_name']")
for i in range(len(divs)):
    divs = driver.find_elements_by_xpath("//div[@class='class_name']")
    div = divs[i]
    print(div.text)
    print(f"Current url 1: {driver.current_url}") # url 
    new_url = url + "/page/"
    time.sleep(2)
    driver.get(new_url)
    print(f"Current url 2: {driver.current_url}") # new_url
    time.sleep(2)
    # Then get info from the new url

    # Go back
    # driver.execute_script("window.history.go(-1)")
    driver.back()
    print(f"Current url 3: {driver.current_url}") # url
    print("Sleeping for 3 seconds from now...")
    time.sleep(3)

您可以尝试在循环中获取特定的 div,如下所示:

divs = driver.find_elements_by_xpath("//div[@class='class_name']")
for i in range(len(divs)):
    div = driver.find_element_by_xpath("(//div[@class='class_name'])[" + (str)i + "]")
    print(div.text)
    print(f"Current url 1: {driver.current_url}") # url 
    new_url = url + "/page/"
    time.sleep(2)
    driver.get(new_url)
    print(f"Current url 2: {driver.current_url}") # new_url
    time.sleep(2)
    # Then get info from the new url

    # Go back
    # driver.execute_script("window.history.go(-1)")
    driver.back()
    print(f"Current url 3: {driver.current_url}") # url
    print("Sleeping for 3 seconds from now...")
    time.sleep(3)

推荐阅读