使用生成器返回结果时出现selenium.common.exceptions.StaleElementReferenceException: Message: stale element refere

原始代码

解析出百度网页上的a标签连接,把解析出的a标签链接以生成器的方式返回:

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.common.exceptions import NoSuchElementException

browser = webdriver.Chrome()


def parse_index():
    a_tags = browser.find_elements(By.CSS_SELECTOR, '#s-top-left a')
    for a_tag in a_tags:
        yield a_tag.get_attribute('href')  # 返回生成器


def main():
    try:
        browser.get('https://www.baidu.com')
        urls = parse_index() # 解析出a标签
        for url in urls:
            browser.get(url)# 访问解析出的a标签连接
    finally:
        browser.close()


if __name__ == '__main__':
    main()

结果报错:

selenium.common.exceptions.StaleElementReferenceException: Message: stale element reference: stale element not found

原因

浏览器访问了新的页面或者刷新了页面,导致元素已经过时,找不到原来页面的元素。

a_tags = browser.find_elements(By.CSS_SELECTOR, '#s-top-left a')
    for a_tag in a_tags:
        yield a_tag.get_attribute('href')  # 返回生成器

每一次遍历生成器,生成器就运行一次a_tag.get_attribute('href'),如果中途浏览器刷新或者访问新的页面,就会导致找不到元素。

解决办法

1、放弃生成器直接以列表形式返回。

def parse_index():
    a_tags = browser.find_elements(By.CSS_SELECTOR, '#s-top-left a')
    return [a_tag.get_attribute('href') for a_tag in a_tags]

2、遍历并访问生成器中的连接时,把生成器转换成列表,这样a_tag.get_attribute('href')一次执行完,也可以防止浏览器刷新时再一次执行该代码。

def main():
    try:
        browser.get('https://www.baidu.com')
        urls = parse_index() # 解析出a标签
        for url in list(urls):  # ---------------------------遍历前先把生成器转换成列表------------------------
            browser.get(url)# 访问解析出的a标签连接
    finally:
        browser.close()

你可能感兴趣的:(selenium,测试工具)