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

如何用Selenium判断元素存在并实现条件分支操作?

问题:处理Selenium中XPath变化的条件分支逻辑

我是Python编程新手,这是我编写的第一个Python脚本。我正在开发一个通过XPath点击网页元素的机器人,希望在目标元素不存在或出现其他元素时返回原页面。

现有代码片段如下:

# Wait for the second web element to be clickable
followbutton = WebDriverWait(driver, 10).until(
    EC.element_to_be_clickable((By.XPATH, "/html/body/div[3]/div/div[2]/div/header[1]/div/div[1]/aside[2]/div/div/div[1]/div[1]/div[2]/button"))
)
followbutton.click()

但有时关注按钮的XPath略有不同,变为/html/body/div[3]/div/div[2]/div/header[1]/div/div[1]/aside[2]/div/div/div[1]/div[1]/div[2]/div/button而非原XPath/html/body/div[3]/div/div[2]/div/header[1]/div/div[1]/aside[2]/div/div/div[1]/div[1]/div[2]/button。

我该如何实现条件分支:若元素对应前者XPath则执行driver.back(),若对应后者则执行followbutton.click()?

以下是完整代码片段供参考:

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 NoSuchElementException
import time

# Create a new instance of the Firefox driver
driver = webdriver.Firefox()

# Set the starting page number
page_num = 32

while True:
    # Navigate to the URL with the current page number
    url = f"https://urlhere.com/page={page_num}"
    driver.get(url)

    time.sleep(20)

    try:
        # Wait for the first web element to be clickable
        user1 = WebDriverWait(driver, 10).until(
            EC.element_to_be_clickable((By.XPATH, "/html/body/div[3]/div/div[2]/div/main/div/div[1]/div/div"))
        )
        user1.click()

        # Wait for 10 seconds
        time.sleep(10)

        # Wait for the second web element to be clickable
        followbutton = WebDriverWait(driver, 10).until(
            EC.element_to_be_clickable((By.XPATH, "/html/body/div[3]/div/div[2]/div/header[1]/div/div[1]/aside[2]/div/div/div[1]/div[1]/div[2]/button"))
        )
        followbutton.click()

        time.sleep(3)
        driver.back()

        # Wait for 5 seconds
        time.sleep(5)
    # 2nd user
        user2 = WebDriverWait(driver, 10).until(
            EC.element_to_be_clickable((By.XPATH, "/html/body/div[3]/div/div[2]/div/main/div/div[2]/div/div"))
        )
        user2.click()
        time.sleep(2)
# 2nd users follow button
        followbutton2 = WebDriverWait(driver, 10).until(
            EC.element_to_be_clickable((By.XPATH, "/html/body/div[3]/div/div[2]/div/header[1]/div/div[1]/aside[2]/div/div/div[1]/div[1]/div[2]/button"))
        )
        followbutton2.click()
        driver.back()

    except:
        # If any exception occurs, break out of the loop
        break

    # Increment the page number
    page_num += 1

# Close the browser window
driver.quit()

解决方案

核心思路是分别检查两个XPath对应的元素是否存在,再根据结果执行对应逻辑。可以通过WebDriverWait结合异常捕获来实现,同时覆盖元素不存在的边界情况。

步骤1:导入必要的异常类

在原有导入基础上,添加TimeoutException:

from selenium.common.exceptions import NoSuchElementException, TimeoutException

步骤2:修改关注按钮的处理逻辑

将原来直接等待单个XPath的代码,替换为嵌套的try-except结构,分别处理两种XPath的情况:

处理第一个用户的关注按钮

# 替换原来的followbutton等待和点击逻辑
try:
    # 检查需要返回原页面的XPath元素是否存在
    WebDriverWait(driver, 10).until(
        EC.presence_of_element_located((By.XPATH, "/html/body/div[3]/div/div[2]/div/header[1]/div/div[1]/aside[2]/div/div/div[1]/div[1]/div[2]/button"))
    )
    driver.back()
except TimeoutException:
    # 第一个元素不存在,检查需要点击的XPath元素
    try:
        followbutton = WebDriverWait(driver, 10).until(
            EC.element_to_be_clickable((By.XPATH, "/html/body/div[3]/div/div[2]/div/header[1]/div/div[1]/aside[2]/div/div/div[1]/div[1]/div[2]/div/button"))
        )
        followbutton.click()
        time.sleep(3)
        driver.back()
    except TimeoutException:
        # 两个元素都不存在,直接返回原页面
        driver.back()

处理第二个用户的关注按钮

同样的逻辑复制到第二个用户的处理部分:

# 替换原来的followbutton2等待和点击逻辑
try:
    # 检查需要返回原页面的XPath元素是否存在
    WebDriverWait(driver, 10).until(
        EC.presence_of_element_located((By.XPATH, "/html/body/div[3]/div/div[2]/div/header[1]/div/div[1]/aside[2]/div/div/div[1]/div[1]/div[2]/button"))
    )
    driver.back()
except TimeoutException:
    # 第一个元素不存在,检查需要点击的XPath元素
    try:
        followbutton2 = WebDriverWait(driver, 10).until(
            EC.element_to_be_clickable((By.XPATH, "/html/body/div[3]/div/div[2]/div/header[1]/div/div[1]/aside[2]/div/div/div[1]/div[1]/div[2]/div/button"))
        )
        followbutton2.click()
        driver.back()
    except TimeoutException:
        # 两个元素都不存在,直接返回原页面
        driver.back()

完整修改后的代码

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 NoSuchElementException, TimeoutException
import time

# Create a new instance of the Firefox driver
driver = webdriver.Firefox()

# Set the starting page number
page_num = 32

while True:
    # Navigate to the URL with the current page number
    url = f"https://urlhere.com/page={page_num}"
    driver.get(url)

    time.sleep(20)

    try:
        # Wait for the first web element to be clickable
        user1 = WebDriverWait(driver, 10).until(
            EC.element_to_be_clickable((By.XPATH, "/html/body/div[3]/div/div[2]/div/main/div/div[1]/div/div"))
        )
        user1.click()

        # Wait for 10 seconds
        time.sleep(10)

        # 处理第一个用户的关注按钮逻辑
        try:
            WebDriverWait(driver, 10).until(
                EC.presence_of_element_located((By.XPATH, "/html/body/div[3]/div/div[2]/div/header[1]/div/div[1]/aside[2]/div/div/div[1]/div[1]/div[2]/button"))
            )
            driver.back()
        except TimeoutException:
            try:
                followbutton = WebDriverWait(driver, 10).until(
                    EC.element_to_be_clickable((By.XPATH, "/html/body/div[3]/div/div[2]/div/header[1]/div/div[1]/aside[2]/div/div/div[1]/div[1]/div[2]/div/button"))
                )
                followbutton.click()
                time.sleep(3)
                driver.back()
            except TimeoutException:
                driver.back()

        # Wait for 5 seconds
        time.sleep(5)
    # 2nd user
        user2 = WebDriverWait(driver, 10).until(
            EC.element_to_be_clickable((By.XPATH, "/html/body/div[3]/div/div[2]/div/main/div/div[2]/div/div"))
        )
        user2.click()
        time.sleep(2)
# 2nd users follow button
        # 处理第二个用户的关注按钮逻辑
        try:
            WebDriverWait(driver, 10).until(
                EC.presence_of_element_located((By.XPATH, "/html/body/div[3]/div/div[2]/div/header[1]/div/div[1]/aside[2]/div/div/div[1]/div[1]/div[2]/button"))
            )
            driver.back()
        except TimeoutException:
            try:
                followbutton2 = WebDriverWait(driver, 10).until(
                    EC.element_to_be_clickable((By.XPATH, "/html/body/div[3]/div/div[2]/div/header[1]/div/div[1]/aside[2]/div/div/div[1]/div[1]/div[2]/div/button"))
                )
                followbutton2.click()
                driver.back()
            except TimeoutException:
                driver.back()

    except Exception as e:
        # If any exception occurs, break out of the loop
        break

    # Increment the page number
    page_num += 1

# Close the browser window
driver.quit()

补充说明

  • 使用presence_of_element_located而非element_to_be_clickable检查第一个XPath,因为我们只需要判断元素是否存在,不需要确保它可点击。
  • 嵌套try-except结构可以覆盖三种情况:第一个元素存在、第二个元素存在、两个元素都不存在。
  • 建议尽量避免使用绝对XPath(从/html开始的路径),页面结构稍有变化就会失效。可以改用相对XPath,比如根据按钮文本或class定位,例如//button[text()='关注']或//div[contains(@class, 'follow-btn-wrap')]/button,稳定性会更高。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 07:25:37