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
相关产品推荐
相关产品推荐

