VBA获取谷歌搜索首条URL时出现Run Time Error '91'错误如何解决
问题根因
- 核心原因是谷歌搜索结果页的DOM结构近期发生了调整,原有定位元素
id="rso"要么已被移除、要么结构层级变化,导致doc.getElementById("rso")返回Nothing,后续调用方法直接触发91错误 - 次要原因:
MSXML2.XMLHTTP请求无浏览器头标识,极容易被谷歌反爬机制拦截,返回人机验证页面而非正常搜索结果,同样不存在rso元素 - 原有代码未做非空校验,只要元素获取失败就直接抛出错误
修复后的可用代码
使用前先在VBA编辑器的「工具-引用」里勾选Microsoft HTML Object Library和Microsoft XML, v6.0:
Sub GetGoogleFirstLink() Dim doc As HTMLDocument Set doc = New HTMLDocument Dim lastrow As Long Dim ecoll As Object Dim link As Object Dim t As Date Dim reqObj As MSXML2.XMLHTTP60 Dim searchUrl As String lastrow = Range("A" & Rows.Count).End(xlUp).Row t = Now() Set reqObj = New MSXML2.XMLHTTP60 For i = 2 To lastrow ' 对关键词做URL编码,避免特殊字符导致请求异常 searchUrl = "https://www.google.co.in/search?q=" & WorksheetFunction.EncodeURL(Cells(i, 1).Value) & "&rnd=" & WorksheetFunction.RandBetween(1, 10000) reqObj.Open "GET", searchUrl, False ' 添加浏览器UA头,降低被反爬拦截的概率 reqObj.setRequestHeader "User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36" reqObj.send doc.body.innerHTML = reqObj.responseText ' 先校验rso元素是否存在,不存在直接跳过避免报错 Set ecoll = doc.getElementById("rso") If Not ecoll Is Nothing Then ' 适配谷歌最新DOM结构,定位搜索结果第一条的有效跳转链接 Set link = ecoll.querySelector("div[jsname] a") If Not link Is Nothing Then ' 清理谷歌跳转前缀,提取真实目标URL并解码 Cells(i, 2) = Split(link.href, "&url=")(1) Cells(i, 2) = Split(Cells(i, 2), "&ved=")(0) Cells(i, 2) = WorksheetFunction.DecodeURL(Cells(i, 2)) Else Cells(i, 2) = "未找到匹配链接" End If Else Cells(i, 2) = "请求被拦截/无搜索结果" End If ' 加1秒延迟,避免请求过快被封IP Application.Wait Now() + TimeValue("00:00:01") Next Set doc = Nothing Set reqObj = Nothing Debug.Print "done" & "Time taken : " & Format(Now() - t, "hh:mm:ss") MsgBox "耗时 - " & Format(Now() - t, "hh:mm:ss") End Sub
可选替代方案
- 方案1:使用谷歌官方自定义搜索API,申请免费密钥后调用接口,完全不存在反爬和DOM结构变动问题,返回结构化JSON可直接提取第一条链接,免费额度为每天100次查询,足够个人日常使用
- 方案2:换用Selenium模拟真实浏览器操作,完全模拟真人搜索行为,反爬抗性更强,适合查询量较大的场景
内容的提问来源于stack exchange,提问作者Rajput
相关产品推荐
相关产品推荐

