You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用while循环移除列表元素?网页测试代码执行异常求助

问题分析与解决方案

首先,我先梳理下你的核心需求:你需要循环打开网页获取版本标识(p1/p2),只要该标识在cluster1列表中,就执行测试函数并将其从列表中移除,直到cluster1为空;但注释掉cluster1.remove(new[-1])时会错误触发else分支,同时当前代码还存在一些逻辑漏洞需要修正。

问题根源

  1. 循环内未重新获取版本值:你的代码只在login1()开头获取了一次new值,进入while循环后没有再次打开网页获取新的版本标识,导致每次判断的都是同一个new[-1]。如果这个值已经被移除出cluster1,就会直接触发else分支退出循环。
  2. 直接修改列表的潜在误解:你提到迭代列表时不能直接移除元素,但你的循环是基于列表长度而非迭代列表本身,所以直接移除是可行的——真正的问题出在没有动态更新版本值上。

修正后的完整代码

我重新调整了代码结构,把版本获取逻辑封装成函数,确保每次循环都能重新获取最新的版本值,同时优化了循环逻辑:

from selenium import webdriver
import unicodedata
import time

new_ver_names = []
cluster1 = ['p1', 'p2']

def get_portal_version():
    # 初始化浏览器、登录并获取版本的封装函数
    ChromeDriver = 'C:\\PortalTesting\\Drivers\\chromedriver.exe'
    chrome_options = webdriver.ChromeOptions()
    chrome_options.add_argument('--no-sandbox')
    chrome_options.add_argument("--incognito")
    chrome_options.add_argument("--window-size=1920x1080")
    
    driver = webdriver.Chrome(executable_path=ChromeDriver, options=chrome_options)
    driver.maximize_window()
    driver.implicitly_wait(130)
    
    try:
        driver.get("MY_URL")
        print("session id ", driver.session_id)
        
        # 登录操作
        username = driver.find_element_by_css_selector("#uid")
        username.send_keys("username")
        password = driver.find_element_by_css_selector("#pid")
        password.send_keys("password")
        login_button = driver.find_element_by_class_name("secondarybtnlabel")
        login_button.click()
        
        # 提取并处理版本值
        dc_elm = driver.find_element_by_xpath('/html/body/div[4]/div/div[2]/span[2]').text
        new = unicodedata.normalize('NFKD', dc_elm).encode('ascii', 'ignore').split()
        portal_version = new[-1]
        print("Portal version: ", portal_version)
        
        # 登出与清理
        logout_btn = driver.find_element_by_xpath('/html/body/div[4]/div[2]/div/div[4]/div/div[2]/div/header/div[2]/table/tbody/tr/td[3]/div/li')
        logout_btn.click()
        driver.delete_all_cookies()
        print("Clearing cookies")
        time.sleep(3)
        
        return portal_version, driver
    except Exception as e:
        print(f"获取版本时出错: {e}")
        driver.quit()
        return None, None

def test1():
    # 替换成你的test1实际逻辑
    print("执行test1...")

def test2():
    # 替换成你的test2实际逻辑
    print("执行test2...")

# 主循环:直到cluster1为空
while cluster1:
    print("cluster1当前长度(循环前):", len(cluster1))
    
    # 每次循环重新获取版本和浏览器实例
    portal_version, driver = get_portal_version()
    
    if not portal_version or not driver:
        print("获取版本失败,退出循环")
        break
    
    if portal_version in cluster1:
        print(f"{portal_version} 在cluster1中,执行测试")
        test1()
        test2()
        new_ver_names.append(portal_version)
        cluster1.remove(portal_version)
        print("cluster1当前长度(循环后):", len(cluster1))
        driver.quit()
    else:
        print(f"{portal_version} 不在cluster1列表中")
        driver.quit()
        # 如果不需要退出循环,可注释掉下面的break,继续尝试获取新值
        # break

print("所有测试执行完成!")

关键优化点说明

  1. 封装版本获取逻辑:把登录、获取版本、登出的代码封装成独立函数,确保每次循环都能重新打开网页获取最新的版本标识,彻底解决旧值重复判断的问题。
  2. 优化循环条件:用while cluster1:替代while len(cluster1) !=0,更符合Python的简洁编码风格,可读性更强。
  3. 独立浏览器实例:每次获取版本后关闭当前浏览器,下次循环重新创建,避免会话冲突或状态残留。
  4. 异常处理:添加异常捕获,防止网页加载失败、元素找不到等情况导致程序直接崩溃。
  5. 列表移除的安全性:你的循环是基于列表是否为空,而非迭代列表元素,所以直接使用cluster1.remove(portal_version)是完全安全的。如果后续cluster1元素较多,建议改用集合(set(['p1','p2'])),集合的in判断和移除操作效率更高。

关于你尝试的列表推导式

你之前的列表推导式逻辑不符合需求,因为它只是固定循环len(cluster1)次,没有关联每次动态获取的网页版本值。列表推导式更适合批量处理已知静态数据,而这里需要动态获取外部网页的动态数据,所以while循环是更合适的选择。

内容的提问来源于stack exchange,提问作者PRK

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 08:57:51