使用Excel无法爬取TSP股价数据,求代码问题排查
问题分析与解决
你遇到的核心问题是TSP网站的股价表格是动态加载的:用MSXML2.XMLHTTP获取的原始HTML里没有实际的股价数据——表格内容是页面加载后通过JavaScript调用后端接口异步拉取的,静态HTML里只有空的容器节点,所以无论怎么调整表格ID/class的选择逻辑,都拿不到有效数据。
另外你代码里存在语法错误:getElementsById应为getElementById(ID是唯一标识,方法名是单数),但即使修正这个错误,静态HTML里依然没有数据。
解决方案1:直接调用TSP公开数据接口(推荐)
TSP提供了直接的CSV数据接口,无需解析HTML,效率更高且更稳定。修正后的VBA代码如下:
Sub FetchTSPSharePricesViaAPI() Dim xhr As Object Dim csvData As String Dim rows() As String Dim cols() As String Dim i As Integer, j As Integer Dim ws As Worksheet ' TSP官方股价历史CSV接口 Dim url As String url = "https://www.tsp.gov/data/fund-share-price-history.csv" Set xhr = CreateObject("MSXML2.XMLHTTP") xhr.Open "GET", url, False xhr.send If xhr.Status = 200 Then ' 拆分CSV数据 csvData = xhr.responseText rows = Split(csvData, vbCrLf) ' 创建新工作表存储数据 Set ws = ThisWorkbook.Sheets.Add ws.Name = "TSP股价历史" ' 逐行解析并写入表格 For i = LBound(rows) To UBound(rows) If Trim(rows(i)) <> "" Then cols = Split(rows(i), ",") For j = LBound(cols) To UBound(cols) ws.Cells(i + 1, j + 1).Value = cols(j) Next j End If Next i MsgBox "数据获取完成,已存入新工作表" Else MsgBox "请求失败:" & xhr.Status & " - " & xhr.statusText End If ' 清理对象 Set xhr = Nothing Set ws = Nothing End Sub
解决方案2:用Selenium模拟浏览器加载(需交互场景)
如果需要模拟页面交互(比如选择特定日期范围),可以用Selenium模拟浏览器加载完整页面:
- 先安装Selenium VBA工具,并配置对应浏览器驱动(如ChromeDriver)
- 使用以下代码:
Sub FetchTSPSharePricesWithSelenium() Dim driver As Object Dim table As Object Dim rows As Object, row As Object Dim cells As Object, cell As Object Dim i As Integer, j As Integer Dim ws As Worksheet ' 初始化Chrome浏览器 Set driver = CreateObject("Selenium.ChromeDriver") driver.Get "https://www.tsp.gov/share-price-history/" ' 等待表格加载完成(最多等待10秒) driver.Wait 10000 ' 定位页面中的股价表格 Set table = driver.FindElementByCss(".share-price-table") Set rows = table.FindElementsByTag("tr") ' 创建新工作表 Set ws = ThisWorkbook.Sheets.Add ws.Name = "TSP股价历史" ' 遍历表格行与单元格,写入数据 i = 1 For Each row In rows Set cells = row.FindElementsByTag("td") If cells.Count > 0 Then j = 1 For Each cell In cells ws.Cells(i, j).Value = cell.Text j = j + 1 Next cell i = i + 1 End If Next row driver.Quit MsgBox "数据抓取完成" ' 清理对象 Set driver = Nothing Set table = Nothing Set ws = Nothing End Sub
关键说明
- 方案1是最优解:直接调用官方接口,速度快、稳定性高,不受页面结构变化影响。
- 方案2适合需要交互的场景,但需要额外配置浏览器驱动,且运行速度较慢。
内容的提问来源于stack exchange,提问作者user18443202
相关产品推荐
相关产品推荐

