使用VBA WinHTTP下载图片被服务器反爬限速,求解决技巧
解决VBA WinHTTP爬取图片被服务器识别为机器人的问题
我正在尝试使用VBA中的WinHTTP组件下载(爬取)图片,编写的代码如下:
Public Function WebFileDownload(ByVal strURL As String, ByVal strFileName As String) As Boolean Dim Buf() As Byte, oWinHttp On Error GoTo Err_Sub Set oWinHttp = CreateObject("WinHttp.WinHttpRequest.5.1") With oWinHttp .Open "GET", strURL, 0 .Send Buf = .ResponseBody End With Open ThisWorkbook.Path & "\" & strFileName For Binary Access Write As #1 Put #1, , Buf Close #1 Set oWinHttp = Nothing WebFileDownload = True Err_Sub: If Err Then MsgBox Err.Description If Not oWinHttp Is Nothing Then Set oWinHttp = Nothing End Function但在下载20-30张图片后,服务器响应速度变得极慢,我推测是被识别为机器人了。我已添加随机休眠时间,但效果不佳,请问有什么可行的解决技巧?
以下是几个有效的解决技巧:
模拟真实浏览器请求头:WinHTTP默认请求头特征明显,容易被识别。添加浏览器常用请求头,甚至准备多个
User-Agent随机切换,同时补充Referer模拟从目标页面跳转的场景:' 可提前准备User-Agent列表,每次随机选取 Dim userAgents As Variant userAgents = Array( _ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36", _ "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/119.0", _ "Mozilla/5.0 (Macintosh; Intel Mac OS X 14_0) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Safari/605.1.15" _ ) With oWinHttp .Open "GET", strURL, 0 .SetRequestHeader "User-Agent", userAgents(Int(Rnd() * UBound(userAgents) + 1)) .SetRequestHeader "Accept", "image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8" .SetRequestHeader "Accept-Language", "zh-CN,zh;q=0.9" .SetRequestHeader "Referer", "https://目标网站的来源页面地址" ' 替换为实际来源页URL .Send Buf = .ResponseBody End With维持会话Cookie:很多网站通过Cookie识别正常用户会话,首次请求后保存服务器返回的Cookie,后续请求带上:
' 声明全局变量存储Cookie Private g_strCookie As String With oWinHttp .Open "GET", strURL, 0 If g_strCookie <> "" Then .SetRequestHeader "Cookie", g_strCookie End If ' 添加其他请求头... .Send ' 更新Cookie If .GetResponseHeader("Set-Cookie") <> "" Then g_strCookie = .GetResponseHeader("Set-Cookie") End If Buf = .ResponseBody End With优化请求频率模式:
- 不要用固定间隔休眠,设置波动范围更大的随机休眠,比如
Application.Wait Now + TimeValue("00:00:" & CStr(Int(Rnd() * 7) + 2)),实现2-8秒的随机停顿。 - 模拟真实用户行为,偶尔插入更长时间的停顿,比如每下载10张图片,休眠10-15秒。
- 避免连续请求同域名资源,若有多个目标域名可穿插请求。
- 不要用固定间隔休眠,设置波动范围更大的随机休眠,比如
IP轮换(进阶方案):如果以上方法无效,可使用代理服务器轮换IP,每次请求随机选择一个代理:
Set oWinHttp = CreateObject("WinHttp.WinHttpRequest.5.1") ' 设置代理,替换为实际可用的代理地址 oWinHttp.SetProxy 2, "http://192.168.1.100:8080" With oWinHttp .Open "GET", strURL, 0 ' 添加请求头... .Send Buf = .ResponseBody End With注意选择可靠的代理资源,避免使用恶意或不稳定的代理。
替换为浏览器模拟工具(备选):若WinHTTP限制过多,可改用
InternetExplorer对象或VBA结合Selenium,完全模拟用户的点击、滚动等行为,被识别概率更低,但运行速度会变慢。
内容的提问来源于stack exchange,提问作者zerom
相关产品推荐
相关产品推荐

