VBA抓取SEB掉期利率网页表格遇错误91,求排查元素定位问题
解决VBA抓取SEB掉期利率表格时的错误91问题
嘿,我来帮你排查这个错误91的问题——这个错误本质是你试图访问一个未被正确初始化的对象属性,也就是html.getElementsByTagName("table")(0)返回了Nothing,你却直接去读它的innerText,自然就报错了。下面一步步分析你遗漏的点和解决方案:
为什么会出现这个问题?
最常见的两个原因:
- 页面是JavaScript动态渲染的:你用
MSXML2.XMLHTTP获取的只是网站的初始静态HTML,而掉期利率表格很可能是页面加载后通过JS异步加载渲染出来的,初始HTML里根本没有<table>元素,所以getElementsByTagName找不到任何表格。 - 元素定位逻辑不严谨:即使页面有静态表格,你直接用索引
(0)取第一个表格的方式很脆弱——如果页面结构调整,第一个表格可能不是你要的目标表格;而且你没有先检查对象是否存在就直接访问属性,一旦找不到就会触发错误91。
解决方案
方案1:改用浏览器自动化(处理动态加载内容)
如果表格是JS动态渲染的,MSXML2.XMLHTTP就无能为力了,需要用InternetExplorer对象模拟浏览器加载页面,等待JS执行完成后再抓取内容:
Dim ie As Object Dim html As New HTMLDocument Dim website As String Dim targetTable As Object Dim tableText As String website = "https://sebgroup.com/large-corporates-and-institutions/prospectuses-and-downloads/rates/swap-rates" ' 初始化IE对象 Set ie = CreateObject("InternetExplorer.Application") ie.Visible = True ' 调试时设为True方便观察,上线后可改为False后台运行 ie.Navigate website ' 等待页面完全加载(包括JS渲染) Do While ie.Busy Or ie.ReadyState <> 4 DoEvents Loop ' 将浏览器渲染后的HTML导入HTMLDocument html.body.innerHTML = ie.Document.body.innerHTML ' 用更精准的选择器定位表格(比如根据页面实际的table属性,这里假设目标表格有data-testid属性) Set targetTable = html.querySelector("table[data-testid='swap-rates-table']") ' 先检查是否找到表格,再访问属性 If Not targetTable Is Nothing Then tableText = targetTable.innerText MsgBox tableText Else MsgBox "未找到目标掉期利率表格,请检查页面结构是否变化" End If ' 清理资源 ie.Quit Set ie = Nothing Set targetTable = Nothing
方案2:优化静态HTML抓取的定位逻辑(仅适用于静态表格)
如果页面确实有静态表格,你需要先验证表格存在性,再调整定位方式:
Dim request As Object Dim response As String Dim html As New HTMLDocument Dim website As String Dim tables As IHTMLElementCollection Dim targetTable As Object Dim tableText As String website = "https://sebgroup.com/large-corporates-and-institutions/prospectuses-and-downloads/rates/swap-rates" Set request = CreateObject("MSXML2.XMLHTTP") request.Open "GET", website, False ' 模拟浏览器请求头,避免被网站拦截 request.setRequestHeader "User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36" request.setRequestHeader "If-Modified-Since", "Sat, 1 Jan 2000 00:00:00 GMT" request.send response = StrConv(request.responseBody, vbUnicode) html.body.innerHTML = response ' 先获取所有表格,检查数量 Set tables = html.getElementsByTagName("table") MsgBox "页面共找到" & tables.Length & "个表格" ' 遍历表格找到目标(或者根据class/id定位) For Each targetTable In tables ' 可以通过表头内容判断是否是目标表格,比如包含"Swap Rates" If InStr(targetTable.innerText, "Swap Rates") > 0 Then tableText = targetTable.innerText MsgBox tableText Exit For End If Next Set request = Nothing Set tables = Nothing Set targetTable = Nothing
你遗漏的关键细节
- 没有考虑动态渲染页面的情况:
MSXML2.XMLHTTP只能抓取静态HTML,无法获取JS生成的内容 - 缺乏对象存在性检查:直接访问
(0)索引的属性,没有先判断对象是否为Nothing - 定位方式太脆弱:依赖表格的索引位置,一旦页面结构变化就会失效,应该用class、id或属性选择器精准定位
内容的提问来源于stack exchange,提问作者Jenny Nygren
相关产品推荐
相关产品推荐

