Excel VBA爬取TSP网站股价表无法获取目标动态表格元素问题
问题根因
- 你用
MSXML2.XMLHTTP60发请求拿到的只是网站返回的初始静态HTML,不会执行页面内嵌的JavaScript脚本,这是拿不到动态表格的核心原因。 - id为
dynamic-share-price-div的外层容器是直接写在静态HTML源码里的,所以你可以正常获取到它的innerHTML;但id为dynamic-share-price-table的div、以及内部的股价表格,都是页面加载完成后由JavaScript动态生成、插入到外层div里的,初始静态响应里完全不存在这部分内容。 - 你拿到的
dynamic-share-price-div在初始源码里是空容器,内部没有table子元素,也没有dynamic-share-price-table这个子节点,所以调用getElementById("dynamic-share-price-table")会返回空值,调用getElementsByTagName("table")(0)也会触发对象不存在的报错。 - 你提到的XPath是浏览器完成JS渲染后最终DOM树的路径,XMLHTTP拿到的未渲染源码里没有对应节点,自然无法匹配。
原实现代码
Sub TSPxmlGet() Dim req As New MSXML2.XMLHTTP60 Dim reqURL As String Dim HTMLDoc As New MSHTML.HTMLDocument Dim HTMLDiv As MSHTML.IHTMLElement Dim HTMLTable As MSHTML.IHTMLElement reqURL = "https://www.tsp.gov/fund-performance/share-price-history/" req.Open "GET", reqURL, False req.send If req.Status <> 200 Then MsgBox req.Status & " - " & req.StatusText Exit Sub End If HTMLDoc.body.innerHTML = req.responseText Set HTMLDiv = HTMLDoc.getElementById("dynamic-share-price-div") 'Set HTMLDiv = HTMLDoc.getElementById("dynamic-share-price-table") 'This one shows that Div element has been populated Debug.Print HTMLDiv.innerHTML 'Will get print in immediate window only for first choice (-div but not -table) 'Set HTMLDiv = HTMLDoc.getElementsByTagName("table")(0) Set HTMLTable = HTMLDiv.getElementsByTagName("table")(0) ' Says object required Debug.Print HTMLTable.innerHTML ' get nothing in immediate window since no object End Sub
解决方法
- 方法1:使用支持JS渲染的页面抓取工具
可以在VBA中调用IE浏览器对象、或者接入Selenium驱动浏览器加载页面,等待页面JS执行完毕、动态表格完全渲染后,再执行DOM定位操作,此时既可以直接通过getElementById("dynamic-share-price-table")获取目标div,也可以通过你提到的XPath定位表格主体。 - 方法2:直接请求数据接口
该页面的股价数据是JS单独向后端发起接口请求获取的,你可以在浏览器中打开目标页面,按F12调出开发者工具,在「网络」面板筛选XHR/ Fetch类型请求,找到返回股价数据的接口,直接用XMLHTTP请求该接口拿结构化数据,不需要解析HTML,稳定性和效率更高。
内容的提问来源于stack exchange,提问作者JWH
相关产品推荐
相关产品推荐

