selenium之批量删除按钮操作

发布于:2024-06-29 ⋅ 阅读:(18) ⋅ 点赞:(0)

具体需求:
需要将某个列表项目中只保留一条数据,但是不确定有没有,所以需要先判断列表中有没有数据,
如果有数据查看是否大于1条,大于1条则删除到只有1条,只有一条则直接进行修改操作;
如果没有数据,则点击添加按钮,添加一条数据;

定位元素如下:

//[@id=“app”]/div[1]/div[2]/div/main/main/form/section[3]

//[@id=“app”]/div[1]/div[2]/div/main/main/form/section[3]/div[3]/div/div/div[1]/div[1]/div[5]/div[2]/table/tbody/tr[1]/td[8]/div/div/button[2]

[@id=“app”]/div[1]/div[2]/div/main/main/form/section[3]/div[3]/div/div/div[1]/div[1]/div[5]/div[2]/table/tbody/tr[2]/td[8]/div/div/button[2]

三个定位元素,第一个是section,后面两个是删除按钮,先统计删除按有几个,如果大于1个则删除所有且只保留第一个;如果只有一个按钮则不删除;使用selenium操作
以下是使用 Selenium 实现上述功能的 Python 代码示例:

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

# 初始化 WebDriver(请根据你的实际情况选择浏览器驱动)
driver = webdriver.Chrome()

# 访问目标页面
driver.get("你的目标页面URL")

# 等待section元素加载
section_xpath = '//*[@id="app"]/div[1]/div[2]/div/main/main/form/section[3]'
WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.XPATH, section_xpath)))

# 获取所有删除按钮
delete_button_xpath = '//*[@id="app"]/div[1]/div[2]/div/main/main/form/section[3]/div[3]/div/div/div[1]/div[1]/div[5]/div[2]/table/tbody/tr/td[8]/div/div/button[2]'
delete_buttons = driver.find_elements(By.XPATH, delete_button_xpath)

# 如果删除按钮数量大于1,删除所有且只保留第一个
if len(delete_buttons) > 1:
    for i in range(1, len(delete_buttons)):
        delete_buttons[i].click()
elif len(delete_buttons) == 1:
    print("只有一个删除按钮,不进行删除操作")

在这段代码中,我们首先初始化 WebDriver 并访问目标页面,然后等待包含删除按钮的 section 元素加载完毕。接着,我们通过 XPath 定位所有删除按钮并统计其数量。如果删除按钮数量大于 1,我们会删除所有按钮并保留第一个。如果只有一个删除按钮,我们则不进行任何删除操作。最后,关闭浏览器。
请确保你的 Selenium WebDriver 和浏览器驱动(如 ChromeDriver)已经正确安装,并替换代码中的 你的目标页面URL 为你实际的目标页面 URL。

实际代码运行后的报错:
selenium.common.exceptions.StaleElementReferenceException: Message: stale element reference: stale element not found in the current frame
遇到 StaleElementReferenceException 错误时,通常是因为页面的 DOM 发生了变化,导致之前找到的元素引用已经失效。可以通过重新查找元素来避免这个错误。以下是改进的代码示例:

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import StaleElementReferenceException

# 初始化 WebDriver(请根据你的实际情况选择浏览器驱动)
driver = webdriver.Chrome()

# 访问目标页面
driver.get("你的目标页面URL")

# 等待section元素加载
section_xpath = '//*[@id="app"]/div[1]/div[2]/div/main/main/form/section[3]'
WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.XPATH, section_xpath)))

# 获取所有删除按钮的XPath
delete_button_xpath = '//*[@id="app"]/div[1]/div[2]/div/main/main/form/section[3]/div[3]/div/div/div[1]/div[1]/div[5]/div[2]/table/tbody/tr/td[8]/div/div/button[2]'

try:
    while True:
        delete_buttons = driver.find_elements(By.XPATH, delete_button_xpath)
        
        # 如果删除按钮数量大于1,删除所有且只保留第一个
        if len(delete_buttons) > 1:
            for i in range(1, len(delete_buttons)):
                try:
                    delete_buttons[i].click()
                except StaleElementReferenceException:
                    # 元素引用过时,重新查找元素并重试
                    delete_buttons = driver.find_elements(By.XPATH, delete_button_xpath)
                    delete_buttons[i].click()
        elif len(delete_buttons) == 1:
            print("只有一个删除按钮,不进行删除操作")
            break
        else:
            # 没有找到任何删除按钮,跳出循环
            break

except StaleElementReferenceException as e:
    print(f"遇到错误:{e}")

# 关闭浏览器
driver.quit()

在这个代码示例中,我们使用了一个 while 循环来处理删除按钮的点击操作。每次点击后会重新查找删除按钮,确保引用是最新的。如果遇到 StaleElementReferenceException,则重新查找元素并重试点击操作。这样可以有效避免元素引用过时的问题。

再次报错内容: except StaleElementReferenceException: # 元素引用过时,重新查找元素并重试 delete_buttons = driver.find_elements(By.XPATH, delete_button_xpath) delete_buttons[i].click()报错:IndexError: list index out of rang

出现 IndexError: list index out of range 错误的原因是,在重新查找元素后,delete_buttons 的长度可能发生了变化,导致 i 超出列表的范围。要解决这个问题,可以在重新查找元素后,确保 i 仍然在新列表的范围内。以下是改进的代码:

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import StaleElementReferenceException
# 初始化 WebDriver(请根据你的实际情况选择浏览器驱动)
driver = webdriver.Chrome()

# 访问目标页面
driver.get("你的目标页面URL")

# 等待section元素加载
section_xpath = '//*[@id="app"]/div[1]/div[2]/div/main/main/form/section[3]'
WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.XPATH, section_xpath)))

# 获取所有删除按钮的XPath
delete_button_xpath = '//*[@id="app"]/div[1]/div[2]/div/main/main/form/section[3]/div[3]/div/div/div[1]/div[1]/div[5]/div[2]/table/tbody/tr/td[8]/div/div/button[2]'

try:
    while True:
        delete_buttons = driver.find_elements(By.XPATH, delete_button_xpath)
        
        # 如果删除按钮数量大于1,删除所有且只保留第一个
        if len(delete_buttons) > 1:
            for i in range(1, len(delete_buttons)):
                try:
                    delete_buttons[i].click()
                except StaleElementReferenceException:
                    # 元素引用过时,重新查找元素并确保索引有效
                    delete_buttons = driver.find_elements(By.XPATH, delete_button_xpath)
                    if i < len(delete_buttons):
                        delete_buttons[i].click()
                    else:
                        # 如果重新查找后索引无效,跳出循环
                        break
        elif len(delete_buttons) == 1:
            print("只有一个删除按钮,不进行删除操作")
            break
        else:
            # 没有找到任何删除按钮,跳出循环
            break

except StaleElementReferenceException as e:
    print(f"遇到错误:{e}")

# 关闭浏览器
driver.quit()

在这个改进版本中,如果捕获到 StaleElementReferenceException,会重新查找元素并检查 i 是否仍在新列表的范围内。如果 i 超出新列表的范围,则跳出循环,避免 IndexError。