zoukankan      html  css  js  c++  java
  • -循环点击遇到的坑(每次点击后返回,页面元素都会变化的解决方法)

    # 前言

    selenium定位一组元素,批量操作循环点击的时候会报错:Element not found in the cache - perhaps the page has changed since it was looked up

    实现目标:批量点击标题,获取每个页面的url地址

    代码如下:

    ```

    # coding:utf-8

    from selenium import webdriver

    driver = webdriver.Firefox()

    driver.get("https://www.cnblogs.com/yoyoketang/")

    all = driver.find_elements_by_css_selector(".postTitle2")

    for i in all:

        i.click()

        print(driver.current_url)   # 打印当前页url

        driver.back()

    ```

    运行结果:

    http://www.cnblogs.com/yoyoketang/p/7259993.html

    Traceback (most recent call last):

    selenium.common.exceptions.StaleElementReferenceException: Message: Element not found in the cache - perhaps the page has changed since it was looked up

    这里不少人就会问了:

    - “为什么第一次点击可以,for循环第二次点击就不行了呢?”

    由于第一次点击后,页面刷新了,我们可以手工点击的时候,注意观察页面,页面是有刷新动作的。

    - “为什么明明定位到了,点击会报错呢?”

    页面刷新后元素的属性是没变,但是element却变了,所有之前定位的元素element都过期了。

    - “那么如何实现呢?”

    如何实现,这个才是本篇重点要讲的。

    一、 分析问题

    1.当页面上有点击行为的时候,页面是会刷新的,为了模拟页面刷新后查看元素是不是会变,我们可以用refresh刷新页面,然后查看刷新前后元素的变化。

    ```

    # coding:utf-8

    from selenium import webdriver

    import time

    driver = webdriver.Firefox()

    driver.get("https://www.cnblogs.com/yoyoketang/")

    all = driver.find_elements_by_css_selector(".postTitle2")

    print(all)  # 刷新前

    driver.refresh()

    all_new = driver.find_elements_by_css_selector(".postTitle2")

    print(all_new)  # 刷新后

    ```

    运行结果:

    [<selenium.webdriver.remote.webelement.WebElement (session="36801e98-3a57-41b1-a58e-021fe925fd57", element="{88a2f797-3833-4ea4-a734-72c5c59800ff}")>, <selenium.webdriver.remote.webelement.WebElement (session="36801e98-3a57-41b1-a58e-021fe925fd57", element="{529248de-6ca0-43d9-8747-34d7dad28c6c}")>,

    ...后面太长省略了]

    2.很明显element里面的值发生了变化,所以第一次点击是可以点的,点完之后,页面刷新了,然后页面上的元素已经发生变化了,第二次循环的时候还是用刷新前的元素去定位点击的,自然就会报错了。

    二、 解决方案

    1.针对页面刷新后,之前的元素失效问题,在for循环体里面可以重新定位一次,覆盖掉之前旧的就行了。

    2.第一次获取全部元素后,通过len函数获取总个数

    3.for循环的时候不要循环定位元素的list对象,换成range函数去循环

    4.参考代码如下:

    ```

    # coding:utf-8

    from selenium import webdriver

    import time

    driver = webdriver.Firefox()

    driver.get("https://www.cnblogs.com/yoyoketang/")

    all = driver.find_elements_by_css_selector(".postTitle2")

    s = len(all)

    print(u"获取总个数:%s"%s)

    for i in range(s):

        all[i].click()

        time.sleep(2)

        url = driver.current_url

        print(u"获取当前页面url:%s"%url)

        driver.back()  # 点完之后返回

        # 重新获取一次元素

        all = driver.find_elements_by_css_selector(".postTitle2")

    ```

    运行结果:

    来源于 : http://mp.weixin.qq.com/s?__biz=MzI5ODU1MzkwMA==&mid=2247484389&idx=1&sn=8a30000edcc0006971401c30d78c5da1&chksm=eca544a6dbd2cdb0a32b72be90fd9a670802ec88653b3bdc64eb5b29c01c467ee53dba772650&mpshare=1&scene=23&srcid=0105WlpnPmvkNSqVTYM36o9H#rd

  • 相关阅读:
    ConcurrentHashMap 实现缓存类
    maven 时区设置&ip&jdk编译版本
    【Hutool】工具类之日期时间工具-DateUtil
    正则表达式
    kafka connector
    kafka
    debezium、kafka connector 解析 mysql binlog 到 kafak
    网络流
    斜率优化
    8.8
  • 原文地址:https://www.cnblogs.com/kaibindirver/p/8205785.html
Copyright © 2011-2022 走看看