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

Selenium可下载Index Holdings下的CSV,切换到Portfolio Holdings后点击CSV按钮超时

Selenium可下载Index Holdings下的CSV,切换到Portfolio Holdings后点击CSV按钮超时

嗨,我来帮你排查这个问题~ 你遇到的超时情况大概率是因为页面里存在两个结构完全一致的CSV按钮元素:切换到Portfolio Holdings标签后,原来Index Holdings面板里的按钮虽然看不到了,但仍然留在DOM中,你的XPath会优先匹配到那个不可见的旧按钮,自然就触发了点击超时的错误。

给你几个针对性的解决思路:

1. 优化XPath,只定位当前激活面板的按钮

切换标签后,当前显示的面板会带有active类,我们可以把这个条件加到XPath里,确保定位到的是当前可见面板中的CSV按钮:

# 修改后的精准XPath,限定到当前激活的标签面板内
csv_xpath = "//div[contains(@class, 'tab-pane') and contains(@class, 'active')]//span[contains(text(), 'Download a Spreadsheet')]/following-sibling::button[contains(text(), 'CSV File')]"

2. 切换标签后,先等待面板加载完成

切换标签后不要立刻点击按钮,先等Portfolio Holdings的面板完全激活并加载好,避免因为内容异步加载导致元素还未就绪:

press_button(wait, driver, tab_xpath)  # 切换到Portfolio Holdings标签
# 等待当前面板处于激活状态
wait.until(EC.presence_of_element_located((By.XPATH, "//div[contains(@class, 'tab-pane') and contains(@class, 'active')]")))
# 再去点击CSV按钮
press_button(wait, driver, csv_xpath)

完整修改后的代码示例

把这些调整整合到你的代码里,大概是这样:

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.support import expected_conditions as EC


def press_button(wait, driver, xpath):
    button = wait.until(EC.element_to_be_clickable((By.XPATH, xpath)))
    ActionChains(driver).move_to_element(button).click().perform()


url = "https://www.sectorspdrs.com/mainfund/XLC"
# 修改后的精准XPath
csv_xpath = "//div[contains(@class, 'tab-pane') and contains(@class, 'active')]//span[contains(text(), 'Download a Spreadsheet')]/following-sibling::button[contains(text(), 'CSV File')]"
tab_xpath = "//a[contains(text(), 'Portfolio Holdings')]"

service = Service(executable_path="chromedriver.exe")
driver = webdriver.Chrome(service=service)
driver.get(url)

wait = WebDriverWait(driver, 10)
press_button(wait, driver, csv_xpath)  # 下载Index Holdings的CSV
press_button(wait, driver, tab_xpath)  # 切换到Portfolio Holdings标签
# 等待面板激活加载
wait.until(EC.presence_of_element_located((By.XPATH, "//div[contains(@class, 'tab-pane') and contains(@class, 'active')]")))
press_button(wait, driver, csv_xpath)  # 下载Portfolio Holdings的CSV

小调试技巧

如果还是有问题,可以先打印页面中匹配原始CSV按钮XPath的元素数量,确认是不是多元素匹配的问题:

buttons = driver.find_elements(By.XPATH, "//span[contains(text(), 'Download a Spreadsheet')]/following-sibling::button[contains(text(), 'CSV File')]")
print(f"找到{len(buttons)}个CSV按钮")

如果输出是2,就说明确实是XPath匹配到了多个元素,那上面的精准XPath方案肯定能解决~

备注:内容来源于stack exchange,提问作者Nathan Oliver

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.13 19:24:50