Selenium核心技巧:元素定位与等待策略
driver.implicitly_wait(20)#隐式等待(放在浏览器启动之后,等待浏览器加载完成)wait.until(lambda d: 1==1)#等待条件。#显示等待(一般放在需要等待的上一个执行代码段)基于元素的属性进行定位。基于链接文件进行定位。
Selenium核心技巧
- WebDriver:浏览器(交互)
- find_element:元素定位
- WebElement元素(交互)
重点内容:
- 元素定位
- 等待
- 元素交互
- 文件上传(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))
更多推荐


所有评论(0)