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

为何使用含变量的contains(text()) XPath表达式搜索耗时过长?

Selenium元素定位耗时过长的优化方案

问题核心原因

你当前的元素定位逻辑慢,不是超时时间设置的问题,主要是XPath表达式效率低下,每次循环都要遍历大量DOM节点,加上重复查询DOM的操作,导致耗时累积增加。

具体优化方案

1. 重构XPath表达式

原XPath先匹配文本再过滤class,会遍历所有包含目标文本的div节点后再筛选class,效率极低。改成先过滤class缩小范围,再匹配文本,能大幅减少遍历的节点数量:

# 精准匹配文本(适合文本无空格的情况)
xpath = "//div[@class='Io6YTe fontBodyMedium' and text()='{}']".format(tlds[i])
# 处理文本含前后空格的情况
xpath = "//div[@class='Io6YTe fontBodyMedium' and normalize-space(text())='{}']".format(tlds[i])

2. 替换为CSS选择器

CSS选择器在浏览器中的解析效率普遍高于XPath,优先使用这种方式:

# 基础写法(部分浏览器支持:contains伪类)
sito = WebDriverWait(driver, 0.2).until(
    EC.presence_of_element_located((By.CSS_SELECTOR, f"div.Io6YTe.fontBodyMedium:contains('{tlds[i]}')"))
).text

如果浏览器不支持:contains()伪类,用JS直接定位更高效:

script = f"""
const elem = document.querySelector('div.Io6YTe.fontBodyMedium');
return elem && elem.textContent.trim() === '{tlds[i]}' ? elem : null;
"""
sito = driver.execute_script(script)
sito = sito.text if sito else None

3. 一次性缓存目标元素

避免循环中重复查询DOM,先批量获取所有符合class的元素,再在本地内存中遍历匹配文本:

# 提前获取所有目标元素
try:
    target_elements = WebDriverWait(driver, 0.2).until(
        EC.presence_of_all_elements_located((By.CSS_SELECTOR, "div.Io6YTe.fontBodyMedium"))
    )
except:
    target_elements = []

# 本地遍历匹配
sito = None
for elem in target_elements:
    elem_text = elem.text.strip()
    if elem_text in tlds:
        sito = elem_text
        print("T2")
        break

4. 确保页面处于稳定状态

如果页面未加载完成,即使设置短超时,WebDriver也会等待页面稳定。循环前先确认页面就绪:

# 等待文档完全加载完成
WebDriverWait(driver, 5).until(lambda d: d.execute_script("return document.readyState") == "complete")

优化后完整代码

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

# 先确保页面加载完成
WebDriverWait(driver, 5).until(lambda d: d.execute_script("return document.readyState") == "complete")

# 提前获取所有目标元素
try:
    target_elements = WebDriverWait(driver, 0.2).until(
        EC.presence_of_all_elements_located((By.CSS_SELECTOR, "div.Io6YTe.fontBodyMedium"))
    )
except:
    target_elements = []

sito = None
for elem in target_elements:
    elem_text = elem.text.strip()
    if elem_text in tlds:
        sito = elem_text
        print("T2")
        break

if not sito:
    print("Cerca sito... 未找到匹配的TLD")

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 07:15:26