Selenium核心技巧

  1. WebDriver:浏览器(交互)  
  2. find_element:元素定位
  3. WebElement元素(交互)     

重点内容:

  1. 元素定位
  2. 等待
  3. 元素交互
    1. 文件上传(3种)
    2. 滚动条处理
    3. JS代码(强制操作)

1、元素定位

  • 方法
    • find_element:如果成功返回元素,如果失败抛出异常。
    • find_elements:如果成功返回list,如果失败返回list(空)
  • 策略
    • 基于元素的属性进行定位
      ID = "id"
      NAME = "name" 
      TAG_NAME = "tag name" 
      CLASS_NAME = "class name"
      
      基于链接文件进行定位
      LINK_TEXT = "link text"
      PARTIAL_LINK_TEXT = "partial link text"
      
      可以定位任意元素
      XPATH = "xpath"
      CSS_SELECTOR = "css selector"

2、等待

  • 1、隐式等待implicitly_wait

    • driver = webdriver.Edge(options=options, service=service)
      driver.implicitly_wait(20)     #隐式等待(放在浏览器启动之后,等待浏览器加载完成)

Selenium 的 implicitly_wait()‌ 是一种‌隐式等待‌机制,用于设置全局的元素查找超时时间。当开启隐式等待后,Selenium 会在每次查找元素时自动等待元素出现,最长等待指定时间,避免因元素未及时加载而导致的定位失败 。

implicitlyWait():implicitlyWait()方法比sleep()方法智能,sleep()方法只能在一个固定的时间等待,而implicitlyWait()可以在一个时间范围内等待,称为隐式等待

隐式等待语法:driver.implicitly_wait(30)   全局设置隐式等待30秒

备注:设置等待时间30s,页面上的元素5s后出现,只等待5s。不会等待30秒


核心特性与工作原理

  • 全局生效‌:只需设置一次,对整个 WebDriver 实例的生命周期内所有元素查找操作都有效 。
  • 智能轮询‌:在设定的时间内,Selenium 会以一定频率(通常为0.5秒)持续检查元素是否存在。一旦找到,立即继续执行,无需等待完整超时时间 。
  • 超时抛出异常‌:如果在设定时间内仍未找到元素,则抛出 NoSuchElementException 异常 。

⚠️ 注意:implicitly_wait() 的单位是‌‌,默认值为0。设置后不可自动关闭,除非显式重置为0 。

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

# 初始化浏览器
driver = webdriver.Chrome()

# 设置隐式等待为10秒
driver.implicitly_wait(10)

# 打开网页
driver.get("https://www.example.com")

# 查找元素(若元素未立即出现,会自动等待最多10秒)
try:
    element = driver.find_element("id", "username")
    element.send_keys("testuser")
except NoSuchElementException:
    print("元素未找到,已超时")

# 关闭浏览器
driver.quit()
  • 2、显示等待WebDriverWait

    WebDriverWait(): 显示等待,针对单个元素生效

    前置条件:导入显示等待包 from selenium.webdriver.support.ui import WebDriverWait

    语法格式如下:WebDriverWait(driver,timeout,poll_frequency=0.5,ignore_exceptions=None)

    driver:WebDriver的驱动程序(IE,火狐,谷歌或远程)
    timeout:最长超时时间,默认以秒为单位
    poll_frequency:休眠时间的间隔(步长)时间,默认为0.5秒(即每500毫秒扫描一次页面)
    ignore_exceptions:超时后的异常信息,默认情况下抛NoSuchElementException异常

    引入WebDriverWait类

    element_obj = WebDriverWait(driver,30,0.5).until(lambda dr:dr.find_element(By.XPATH,'//div'))

    • import os
      from selenium import webdriver
      from selenium.webdriver.common.by import By
      from  selenium.webdriver.support.ui import WebDriverWait  # 显示等待类
      
      
      current_path = os.path.dirname(os.path.abspath(__file__))  # 当前路径
      driver_path = os.path.join(current_path,'../webdriver/chromedriver.exe')  # driver路径
      pages_path = os.path.join(current_path,'../pages/wait.html')  # 本地网页路径
      driver = webdriver.Chrome(executable_path=driver_path)  # Firefox,Ie等
      
      driver.get('file://%s'%pages_path)  # 本地网页打开file://  打开部署好的站点http://
      driver.find_element(By.XPATH,'//button').click()
      # 显示等待:1、单个元素设置生效 2、页面扫描时间可以自定义配置
      element_obj = WebDriverWait(driver,30,0.5).until(lambda dr:dr.find_element(By.XPATH,'//div'))
      print( element_obj.get_attribute('class') )  # 获取class属性值
      
          

      #显示等待(一般放在需要等待的上一个执行代码段) # WebDriverWait(driver,timeout=10).until(lambda x: driver.find_element(By.XPATH, value='//*[@id="s-top-left"]/a[1]')) wait=WebDriverWait(driver, 10) wait.until(lambda d: 1==1) #等待条件 #el=driver.find_element(by='xpath', value='//*[@id="s-top-left"]/a[1]') el=driver.find_element(By.XPATH, value='//*[@id="s-top-left"]/a[1]')
  • 3、流畅等待(更高级的等待)

  • 4、强制等待(休眠)sleep

    sleep():固定休眠时间设置,python的time包里提供了休眠方法sleep,导入包后就能使用;sleep()方法以秒为单位,如果超时设置小于1秒,可以使用小数

    导入包:import time

    time.sleep(2)  固定等待2秒

    time.sleep(0.5)  固定等待0.5秒

    • #强制等待
      import time
      time.sleep(3)

3、until、until_not的区别

在 Selenium 中,until 和 until_not 是 WebDriverWait 类提供的两个关键方法,用于实现显式等待。它们的主要区别在于判断条件的逻辑:

  • until(method, message='')‌:

    • 功能‌:等待直到指定的条件 method 返回 True
    • 执行逻辑‌:只要 method 的返回值为 True,就停止等待并继续执行后续代码。如果在设定的超时时间内 method 始终返回 False,则抛出 TimeoutException 异常。
    • 使用场景‌:常用于等待某个元素出现、可见、可点击,或者页面标题匹配等条件成立。
  • until_not(method, message='')‌:

    • 功能‌:等待直到指定的条件 method 返回 False 或者抛出异常。
    • 执行逻辑‌:只要 method 的返回值为 True,就继续等待。只有当 method 的返回值变为 False 时,才停止等待并继续执行后续代码。如果在设定的超时时间内 method 始终返回 True,则抛出 TimeoutException 异常。
    • 使用场景‌:常用于等待某个元素消失、不可见,或者某个条件不再成立。

总结来说‌:

  • until 等待 ‌条件成立‌(返回 True)。
  • until_not 等待 ‌条件不成立‌(返回 False)。

这两个方法通常与 expected_conditions 模块一起使用,例如 EC.presence_of_element_located 或 EC.element_to_be_clickable 等条件判断函数作为 method 参数传入。

4、WebDriverWait‌ 

WebDriverWait‌ 是 Selenium 中用于实现‌显式等待‌的核心类,它允许脚本在执行下一步前,等待某个特定条件成立(如元素出现、可见、可点击等),避免因页面加载延迟导致的自动化失败。

基本用法

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

# 创建 WebDriverWait 实例,最多等待 10 秒
wait = WebDriverWait(driver, 10)

# 等待元素出现在 DOM 中
element = wait.until(EC.presence_of_element_located((By.ID, "kw")))

# 等待元素可见
element = wait.until(EC.visibility_of_element_located((By.ID, "kw")))

# 等待元素可点击
element = wait.until(EC.element_to_be_clickable((By.ID, "submit")))

关键参数说明

  • driver‌: 浏览器驱动实例(如 Chrome())。
  • timeout‌: 最长等待时间(单位:秒),默认 10 秒。
  • poll_frequency‌: 轮询检查条件的间隔,默认 0.5 秒。
  • ignored_exceptions‌: 忽略的异常类型(默认忽略 NoSuchElementException)。

常用 expected_conditions 条件

  • presence_of_element_located(locator):元素存在于 DOM(不一定可见)。
  • visibility_of_element_located(locator):元素可见(宽高均 > 0)。
  • element_to_be_clickable(locator):元素存在且可见且可点击。
  • text_to_be_present_in_element(locator, text):元素包含指定文本。
  • alert_is_present():等待弹窗出现。
  • invisibility_of_element_located(locator):元素不可见或已移除。
  • staleness_of(element):元素已从 DOM 中移除(常用于等待页面刷新)。

自定义等待条件(使用 lambda)

# 等待元素出现,使用匿名函数
element = wait.until(lambda d: d.find_element(By.ID, "kw"))

推荐实践

  • 优先使用显式等待‌,而非 time.sleep() 或隐式等待,因其更灵活、高效。
  • 可结合隐式等待使用:设置全局隐式等待(如 driver.implicitly_wait(5)),再对关键元素使用显式等待。
  • 显式等待仅对当前操作生效,需为每个动态元素单独设置。

5、实例代码

wait_info = (By.XPATH, '//*[@id="app"]/div[1]/div[2]/div[2]/div[1]/div[2]/div/div[1]/div/div[1]/i')

#--------------------------------------------------

# 因为页面加载时间长,需要延时等待
# # 下列代码:正常
# WebDriverWait(drivers, timeout=10).until(
#     lambda x: drivers.find_element( By.XPATH, value='//*[@id="app"]/div[1]/div[2]/div[2]/div[1]/div[2]/div/div[1]/div/div[1]/i'))

# # 下列代码:正常
# name, value = login.wait_info
# WebDriverWait(drivers, timeout=10).until(
#     lambda x: drivers.find_element( By.XPATH, value=value))

# 下列代码:错误。login.wait_info 应该传地址
# WebDriverWait(drivers, timeout=10).until(lambda x: drivers.find_element(login.wait_info))

# 因为页面加载时间长,需要延时等待
# 下列代码:正常
WebDriverWait(drivers, timeout=10).until(lambda x: drivers.find_element(*login.wait_info))

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐