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

VBA脚本用ServerXMLHTTP代理请求卡第一个代理,如何遍历全部代理?

解决VBA ServerXMLHTTP代理遍历卡住的问题

看起来你的脚本卡在第一个代理的核心原因是复用了同一个ServerXMLHTTP对象,导致前一次请求的状态、错误或资源残留影响了后续循环。另外,错误处理的方式也可能掩盖了问题,让脚本无法正常推进到下一个代理。下面是具体的修复方案和修改后的代码:

问题分析

  1. 对象复用导致状态残留:你在循环外创建了Http和Html对象,每次请求后这些对象的内部状态(比如错误标记、未释放的连接)不会自动重置,可能导致后续请求无法正常发起。
  2. 错误处理范围过大:On Error Resume Next覆盖了整个With Http块,可能隐藏了send或responseText解析中的错误,导致代码停在某个步骤无法继续循环。
  3. 超时参数不合理:你设置的连接/发送超时长达10分钟(600000毫秒),如果第一个代理不可用,脚本会等待很久才会超时,看起来像是“卡住”了。

修复方案

  • 每次循环重新创建对象:在For Each循环内部初始化ServerXMLHTTP60和HTMLDocument,确保每次请求都是全新的上下文。
  • 精准控制错误处理:只在send和readyState等待阶段使用错误捕获,之后立即恢复错误处理,便于排查问题。
  • 调整超时参数:缩短连接和发送超时(比如设为5秒),避免长时间等待;接收超时可以适当延长(比如30秒)。
  • 清理对象引用:每次循环结束后释放对象,避免内存泄漏。

修改后的代码

Sub MakeProxiedRequests()
    Dim Http As ServerXMLHTTP60, Html As HTMLDocument
    Dim elem As Object, proxyList As Variant, oProxy As Variant
    Dim requestSuccess As Boolean
    Dim startTime As Double
    
    proxyList = Array( _
        "191.96.42.184:3129", _
        "138.197.108.5:3128", _
        "35.245.145.147:8080", _
        "173.46.67.172:58517", _
        "191.96.42.82:3129", _
        "157.55.201.224:8080", _
        "67.205.172.239:3128", _
        "191.96.42.106:3129" _
    )
    
    For Each oProxy In proxyList
        requestSuccess = False
        startTime = Timer
        Debug.Print "Trying with proxy: " & oProxy
        
        ' 每次循环创建新的对象实例
        Set Http = New ServerXMLHTTP60
        Set Html = New HTMLDocument
        
        With Http
            .Open "GET", "https://stackoverflow.com/questions/tagged/web-scraping", True
            .setRequestHeader "User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36"
            .setProxy 2, oProxy
            ' 调整超时:连接超时5秒,发送超时5秒,接收超时30秒
            .setTimeouts 5000, 5000, 30000, 30000
            
            On Error Resume Next
            .send
            ' 等待请求完成或超时
            While .readyState < 4
                DoEvents
                ' 额外检查是否超时(可选,避免无限等待)
                If Timer - startTime > 35 Then ' 比接收超时多5秒缓冲
                    Exit While
                End If
            Wend
            On Error GoTo 0
            
            ' 检查请求是否成功
            If .Status = 200 Then
                Html.body.innerHTML = .responseText
                Set elem = Html.querySelectorAll(".summary .question-hyperlink")
                If Not elem Is Nothing And elem.Length > 0 Then
                    Debug.Print "Success! First question: " & elem(0).innerText
                    requestSuccess = True
                End If
            End If
        End With
        
        ' 释放对象
        Set Http = Nothing
        Set Html = Nothing
        Set elem = Nothing
        
        If Not requestSuccess Then
            Debug.Print "Failed with proxy: " & oProxy
        End If
    Next oProxy
End Sub

关键修改说明

  1. 对象实例化移到循环内:每次循环都创建新的ServerXMLHTTP60和HTMLDocument,彻底避免状态残留问题。
  2. 优化错误处理:仅在send和等待阶段使用On Error Resume Next,之后立即恢复正常错误处理,防止隐藏其他问题。
  3. 超时参数调整:缩短连接和发送超时,减少等待时间;同时添加了一个超时检查的额外保险,避免因readyState不更新导致的无限等待。
  4. 状态检查:通过.Status = 200判断请求是否成功,而不是仅仅依赖元素是否存在,判断逻辑更准确。

这样修改后,脚本会逐个遍历所有代理,无论某个代理是否可用,都会继续执行下一个,直到整个列表处理完毕。

内容的提问来源于stack exchange,提问作者robots.txt

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 06:59:32