You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Excel VBA中XMLHTTP GET请求无法获取目标URL响应(405错误)

解决Excel VBA XMLHTTP请求NSEIndia时的405错误

我正尝试用Excel VBA的XMLHTTP GET方法抓取NSEIndia网站的表格数据,请求主页面Url_Main和Url_Sub1都正常,但请求目标接口Url_Sub2时返回HTTP 405错误,以下是相关代码和截图:

问题代码

Option Explicit
Dim xmlhttp As New MSXML2.XMLHTTP60,html As New HTMLDocument
Dim sResp$, Url_Main$, Url_Sub1$, Url_Sub2$


Sub FetchHistoricalDataWorking()
    
    'URL
        Url_Main$ = "https://www1.nseindia.com/products/content/equities/equities/eq_security.htm"
        
        Url_Sub1$ = "https://www1.nseindia.com/marketinfo/sym_map/symbolCount.jsp?symbol=LUPIN"
        Url_Sub2$ = "https://www1.nseindia.com/products/dynaContent/common/productsSymbolMapping.jsp?symbol=LUPIN&segmentLink=3&symbolCount=2&series=ALL&dateRange=3month&fromDate=&toDate=&dataType=PRICEVOLUMEDELIVERABLE"
      
    'XML Link
        With xmlhttp
            .Open "GET", Url_Main$, False '/products/content/equities/equities/eq_security.htm"
            .setRequestHeader "User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36"
            .setRequestHeader "Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9"
            .setRequestHeader "Accept-Encoding", "gzip, deflate, br"
            .setRequestHeader "Accept-Language", "en-IN,en-US;q=0.9,en;q=0.8"
            .setRequestHeader "Cache-Control", "no-cache"
            .setRequestHeader "Connection", "keep-alive"
            .setRequestHeader "Host", "www1.nseindia.com"
            .send
            While .readyState < 4: DoEvents: Wend
            
            .Open "GET", Url_Sub1$, False
            .setRequestHeader "User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36"
            .setRequestHeader "Referer", Url_Main$
            .setRequestHeader "Accept", "*/*"
            .setRequestHeader "Accept-Encoding", "gzip, deflate, br"
            .setRequestHeader "Accept-Language", "en-IN,en-US;q=0.9,en;q=0.8"
            .setRequestHeader "Cache-Control", "no-cache"
            .setRequestHeader "Connection", "keep-alive"
            .setRequestHeader "Host", "www1.nseindia.com"
            .send
            While .readyState < 4: DoEvents: Wend
            
            .Open "GET", Url_Sub2$, False
            .setRequestHeader "User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36"
            .setRequestHeader "Referer", Url_Main$
            .setRequestHeader "Accept", "*/*"
            .setRequestHeader "Accept-Encoding", "gzip, deflate, br"
            .setRequestHeader "Accept-Language", "en-IN,en-US;q=0.9,en;q=0.8"
            .setRequestHeader "Cache-Control", "no-cache"
            .setRequestHeader "Connection", "keep-alive"
            .setRequestHeader "Host", "www1.nseindia.com"
            .send
            While .readyState < 4: DoEvents: Wend
            
            sResp = .responseText
            Debug.Print sResp
        End With

        html.body.innerHTML = sResp
    '       Debug.Print oHttp.readyState & oHttp.Status
         
End Sub

相关截图

  • 所需输出表格:所需输出表格
  • 网络工具发起源:网络工具发起源
  • Url_Sub1请求响应:Url_Sub1请求响应
  • Url_Sub2请求405错误:Url_Sub2请求405错误
  • 网络工具详情:网络工具详情

解决方案

HTTP 405错误意味着服务器不允许使用当前请求方法(此处为GET)访问目标资源,针对NSEIndia的接口特性,可通过以下方式排查修复:

1. 确认请求方法是否正确

打开浏览器开发者工具,查看Url_Sub2对应的实际请求方法。如果浏览器使用POST而非GET,需将VBA代码中的请求方式改为POST,并把URL中的参数作为表单数据提交。

2. 优化会话Cookie处理

NSEIndia依赖Cookie验证会话合法性,建议改用MSXML2.ServerXMLHTTP60替代MSXML2.XMLHTTP60,它在Cookie自动管理上更稳定,能确保后续请求携带主页面返回的会话Cookie。

3. 精简并对齐请求头

  • 移除Accept-Encoding头:XMLHTTP60无法自动解压压缩内容,会导致响应解析异常,直接让服务器返回未压缩文本。
  • 移除Cache-Control和Host头:这些头会由ServerXMLHTTP60自动生成,手动设置可能引发冲突。
  • 确保Referer头与浏览器一致,通常为Url_Main。

修改后的示例代码

Option Explicit
Dim xmlhttp As New MSXML2.ServerXMLHTTP60, html As New HTMLDocument
Dim sResp$, Url_Main$, Url_Sub1$, Url_Sub2$

Sub FetchHistoricalDataFixed()
    'URL定义
    Url_Main = "https://www1.nseindia.com/products/content/equities/equities/eq_security.htm"
    Url_Sub1 = "https://www1.nseindia.com/marketinfo/sym_map/symbolCount.jsp?symbol=LUPIN"
    Url_Sub2 = "https://www1.nseindia.com/products/dynaContent/common/productsSymbolMapping.jsp?symbol=LUPIN&segmentLink=3&symbolCount=2&series=ALL&dateRange=3month&fromDate=&toDate=&dataType=PRICEVOLUMEDELIVERABLE"
      
    '初始化会话并获取会话Cookie
    With xmlhttp
        .Open "GET", Url_Main, False
        .setRequestHeader "User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36"
        .setRequestHeader "Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8"
        .setRequestHeader "Accept-Language", "en-IN,en-US;q=0.9,en;q=0.8"
        .setRequestHeader "Connection", "keep-alive"
        .send
        While .readyState < 4: DoEvents: Wend
        
        '请求Url_Sub1
        .Open "GET", Url_Sub1, False
        .setRequestHeader "User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36"
        .setRequestHeader "Referer", Url_Main
        .setRequestHeader "Accept", "*/*"
        .setRequestHeader "Accept-Language", "en-IN,en-US;q=0.9,en;q=0.8"
        .setRequestHeader "Connection", "keep-alive"
        .send
        While .readyState < 4: DoEvents: Wend
        
        '请求Url_Sub2
        .Open "GET", Url_Sub2, False
        .setRequestHeader "User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36"
        .setRequestHeader "Referer", Url_Main
        .setRequestHeader "Accept", "*/*"
        .setRequestHeader "Accept-Language", "en-IN,en-US;q=0.9,en;q=0.8"
        .setRequestHeader "Connection", "keep-alive"
        .send
        While .readyState < 4: DoEvents: Wend
        
        '输出响应状态与内容
        If .Status = 200 Then
            sResp = .responseText
            Debug.Print sResp
        Else
            Debug.Print "请求失败,状态码:" & .Status
        End If
    End With

    html.body.innerHTML = sResp
End Sub

4. 额外提示

NSEIndia的反爬机制会定期更新,如果上述调整后仍未解决,需再次对比浏览器中的完整请求头(包括Cookie、Origin等),确保VBA请求头与浏览器完全一致。


内容的提问来源于stack exchange,提问作者Sourav

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 01:20:37