Excel VBA 爬取网页数据触发运行时错误91(对象未设置)排查
报错原因说明
- 错误91的触发根源是:点击查询按钮后的加载等待逻辑,仅校验了IE整体的忙碌状态和加载完成标识,没有对目标数据表格
example3的DOM渲染状态做校验 - 当页面DOM渲染速度慢于IE整体状态返回完成的节奏时,第一次读取
doc.getElementById("example3")会返回空对象,后续链式调用子节点方法就会触发91中断;此时按F5继续时,表格已经完成渲染,就能正常读取数据,所以会出现"同一位置反复中断、按继续就能跑通"的现象。
可直接落地的修复方案
- 把原代码里固定时长的等待逻辑,替换为目标节点存在性循环校验,避免因为固定等待时长和页面实际渲染节奏不匹配导致的空对象问题。
- 关键修复代码段(替换原代码中点击查询后到写入单元格的逻辑即可):
' 点击查询按钮后,增加表格节点校验逻辑 Dim dataTable As Object, retryTimes As Integer retryTimes = 0 Do DoEvents On Error Resume Next Set dataTable = doc.getElementById("example3") On Error GoTo 0 retryTimes = retryTimes + 1 Application.Wait Now + TimeValue("00:00:01") ' 最多循环20次,避免页面无数据时死循环 Loop Until Not dataTable Is Nothing Or retryTimes >= 20 ' 校验到表格存在后再执行写入 If Not dataTable Is Nothing Then With ws .Range("L" & i).Value = dataTable.getElementsByTagName("tr").Item(1).getElementsByTagName("td").Item(3).innerText .Range("M" & i).Value = dataTable.getElementsByTagName("tr").Item(1).getElementsByTagName("td").Item(5).innerText .Range("N" & i).Value = dataTable.getElementsByTagName("tr").Item(1).getElementsByTagName("td").Item(12).innerText .Range("O" & i).Value = dataTable.getElementsByTagName("tr").Item(1).getElementsByTagName("td").Item(11).innerText End With End If
- 额外代码修正点:
- 原代码最后对象释放顺序错误:先执行
Set IE = Nothing再调用IE.Quit会触发对象已释放的报错,需要调整为先调用IE.Quit,再执行对象置空 - 读取表格行、列节点时,增加节点数量的边界判断,避免因为页面返回的表格行数/列数不足触发越界报错
- 原代码中固定等待3秒、5秒的逻辑会大幅拖慢运行效率,替换为节点校验逻辑后,整体运行速度会明显提升
- 原代码最后对象释放顺序错误:先执行
内容的提问来源于stack exchange,提问作者Sayed Ali
相关产品推荐
相关产品推荐

