ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

搜索
EH技术汇-专业的职场技能充电站 妙哉!函数段子手趣味讲函数 Excel服务器-会Excel,做管理系统 效率神器,一键搞定繁琐工作
HR薪酬管理数字化实战 Excel 2021函数公式学习大典 Excel数据透视表实战秘技 打造核心竞争力的职场宝典
让更多数据处理,一键完成 数据工作者的案头书 免费直播课集锦 ExcelHome出品 - VBA代码宝免费下载
用ChatGPT与VBA一键搞定Excel WPS表格从入门到精通 Excel VBA经典代码实践指南
查看: 32316|回复: 54

[分享] 在winHttp中使用同步与异步。。。

  [复制链接]

TA的精华主题

TA的得分主题

发表于 2015-5-2 22:43 | 显示全部楼层 |阅读模式
本帖已被收录到知识树中,索引项:网页交互
本帖最后由 浮华、缠绕指尖 于 2015-5-2 23:07 编辑

在VBA中的网抓,个人更倾向于使用winHttp对象,(即createobject("winHttp.winHttprequest.5.1")对象,前期引用为Microsoft WinHttp开始的),逐渐摒弃了刚学网抓时的xmlHttp对象。一个最主要的原因是winHttp相对于xmlHttp更底层一些,对于cookie的共享,xmlhttp的cookie主要存在于两部分,第一是IE,第二是Office本身中,有点相当于是长期存在的感觉,所以清缓存这一步就变得相对复杂,先要清除IE然后在重启Office。而在winHttp中对于这一点就变得相对简单了,sub一结束cookie就Game Over了。

为什么我会这么在乎cookie呢,一个是实时更新,一个是存在登录的,具体原因大家可想而知。所以在我的网抓中几乎很少涉及到模拟cookie这一步。

再来简单的说说winHttp对象,winHttp中有六大属性,十二大方法以及四个事件,分别如下:

属性
方法
事件
Status
SetProxy
OnError
StatusText
SetCredentials
OnResponseDataAvailable
ResponseText
Open
OnResponseFinished
ResponseBody
SetRequestHeader
OnResponseStart
ResponseStream
GetResponseHeader

Option
GetAllResponseHeaders


Send


WaitForResponse


Abort


SetTimeouts


SetClientCertificate


SetAutoLogonPolicy

同步和异步的设置是在Open方法中,即:

Sub Open(Method As String, Url As String, [Async]),最后一个parameter设置成true时为异步,false为同步

这里来讨论一下winHttp中同步和异步方式的异同:

同步
异步
阻塞线程(大量翻页过程中假死,相信很多人都遇到过) 不会阻塞纯程,所以也就不会假死(卡界面)
支持四种超时(ResolveTimeout, ConnectTimeout, SendTimeout, ReceiveTimeout),分别为DNS解析,连接,发送以及接受 只支持一种超时,那就是等待,如果在设置的时间内没有数据,那么就是超时
~ 支持回调,换句话说就是CallBack或者是Event

评分

5

查看全部评分

TA的精华主题

TA的得分主题

 楼主| 发表于 2015-5-2 23:07 | 显示全部楼层

继续。。。

还有一个重要的区别,可能很少人会注意到,在同步模式中,会一直保持之前的Cookie,但是在异步过程中却不带Cookie,所以对于这一点大家需慎用。

异步。。上面中提到了一个重要的知识点:回调。换句话说就是从解析DNS开始直到接收到Data的过程中(也就是说在设置一定等待的时间内),可以让office执行其他的子过程,虽然很少人能用到,或不了解或不需要,这就可以将等待的这段时间内完成别的事情,这就是异步。

那么这时问题就来了,怎么实现回调过程呢?先留个疑问,看大家各自有啥好想法(提示,类)。。

隔段时间在上传附件。。。


TA的精华主题

TA的得分主题

发表于 2015-5-2 23:17 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册

TA的精华主题

TA的得分主题

 楼主| 发表于 2015-5-2 23:55 | 显示全部楼层
liucqa 发表于 2015-5-2 23:17
http://www.exceltip.net/thread-38586-1-1.html

呵呵,老师的速度真快,看了链接,确实介绍了怎么回调,但没有阐诉明白。。。他直接这样很容易造成数据丢失的

TA的精华主题

TA的得分主题

发表于 2015-6-5 21:18 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
浮华、缠绕指尖 发表于 2015-5-2 23:55
呵呵,老师的速度真快,看了链接,确实介绍了怎么回调,但没有阐诉明白。。。他直接这样很容易造成数据丢 ...

你还继续写不?我等着放知识树呢。

TA的精华主题

TA的得分主题

 楼主| 发表于 2015-6-5 23:11 | 显示全部楼层
liucqa 发表于 2015-6-5 21:18
你还继续写不?我等着放知识树呢。

我原以为都没几个人需要,所以之前就没啥兴趣写了
好吧,既然老师觉得还可以的话,那我就抽时间继续完善了

TA的精华主题

TA的得分主题

 楼主| 发表于 2015-6-6 20:29 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助

一般在VBA中实现异步的方法,总归分为两大类:其一为“等待”,其二为“回调"。

等待又可以包括,WaitForResponse和轮询两种:

一、使用WaitForResponse:

Sub Wait()
Dim winHttp As New winHttp.WinHttpRequest
      With winHttp
            .Open "GET", URL, True
            .Send
            .WaitForResponse
            Debug.Print .ResponseText
      End With
End Sub

其二、使用轮询,IE或者xmlHttp中常见:

Sub test()
Dim xmlHttp As New MSXML2.xmlHttp
With xmlHttp
      .Open "GET", url, True
      .send
      While .readyState <> 4
            Debug.Print "获取数据中。。"
            DoEvents
      Wend
      Debug.Print "获取数据完成。。"
End With
End Sub

最后是回调,推荐!!

老师在二楼中给了一个链接,主要是在工作薄中实现回调过程的,暂就使用类模块来实现一个简单的回调

第一步,新建一个类模块,命令为winHttpClass,在此类模块中键入代码如下,当然在事件中可以选择相应的事件

Option Explicit
Public WithEvents winHttp As winHttp.WinHttpRequest

Private Sub Class_Initialize()
Set winHttp = CreateObject("winhttp.winhttprequest.5.1")
End Sub

Private Sub winHttp_OnError(ByVal ErrorNumber As Long, ByVal ErrorDescription As String)
      Debug.Print "发生错误啦。"
End Sub

Private Sub winHttp_OnResponseDataAvailable(Data() As Byte)
      Debug.Print "有数据传传输进来了"
End Sub

Private Sub winHttp_OnResponseFinished()
      Debug.Print "数据接受完成"
End Sub

Private Sub winHttp_OnResponseStart(ByVal Status As Long, ByVal ContentType As String)
      Debug.Print "开始接收数据"
End Sub

最后在一个标准模块中来调回此类,来实现请求,比如

Sub test()
Dim winHttp As New winHttpClass
      With winHttp.winHttp
            .Open "get", url, True
            .send
      End With
End Sub

如果有人跟着我一步步的做的话,你最后会发现,按F5运行的时候却怎么也运行不了来代码,而只有F8单步调试的时候可以运行

至此,再留一个疑问。。。

晚些再找一些实例来分享给各位,当然,如果大家有好的实例的话,也可以共享嘛。。




TA的精华主题

TA的得分主题

 楼主| 发表于 2015-6-7 08:29 | 显示全部楼层
本帖最后由 浮华、缠绕指尖 于 2015-6-7 10:08 编辑

接上。。先解释为什么我上面那个只有在“按F5运行的时候却怎么也运行不了来代码,而只有F8单步调试的时候可以运行”

其实这点不难解释,如果大家都有用过控件的类的话,应该知道,一般都要在将这个引用的新类定义成全局变量,比如

Option Explicit
Dim arr(1 To 10) As New myClass
Sub test()
      '所需的代码
End Sub

如果要是定义成sub中的局部变量,那么这个类的事件自然起不到任何作用,原因很简单,当这个sub运行结束的时候,这个局部变量已经被回收了。。

那好,我下面通过一定的动画以及具体动画来展示一下什么是异步

网址都借用老师在测试同步采集和异步采集的速度差异中的地址:网址

其一、等待类的(WaitForResponse)

效果其一、

等待类1.gif

效果其二、

等待类2.gif

效果一可能看不出什么的异常,但是效果二就相当明显了,因为你在同步的时候可以手动去新建一个窗体一类的吗?

附件如下:

winHttp异步之等待类.rar (25.55 KB, 下载次数: 659)

评分

1

查看全部评分

TA的精华主题

TA的得分主题

 楼主| 发表于 2015-6-7 08:39 | 显示全部楼层
本帖最后由 浮华、缠绕指尖 于 2015-6-7 08:40 编辑

二、回调,无需等待。
异步.gif
注意到其的下载顺序与速度。
附件如下
winHttp异步之回调.rar (28.17 KB, 下载次数: 860)

评分

2

查看全部评分

TA的精华主题

TA的得分主题

 楼主| 发表于 2015-6-7 08:59 | 显示全部楼层

可能大家对第二种方式很感兴趣,速度在那儿放着的,但往往是这一点,需要特别注意的是,如果一次性并发过大的话,很容易造成不必要的数据丢失,就好比你的打算下一部电影,但你的网速在那儿限制着,没办法一次性下载完成,所以不可能在winHttp默认的超时时间内完成所需要的数据。



换句话说,这个取决于自身的网速限制以及电脑自身的性能,如果是超时的话,可以在winHttp_OnError的事件进行重新发报。。

最后。采用异步的话在Post发报的时候与正常的同步在书写过程还有一定的差异,因为在同步中cookie或报文都是存在于同一个对象中,但是异步的Post中,却不会存在于同一个对象中,所以winHttp的异步发送方式中需要自己去模拟cookie等报文。。具体如何模拟就不细说了。。

呵呵,大致完工。如果其中有啥歧义或者有误的地方,可以提出来,个人也只是分享自己的一点心得而已。呵呵。。







您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

手机版|关于我们|联系我们|ExcelHome

GMT+8, 2024-12-23 04:25 , Processed in 0.045220 second(s), 9 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

沪公网安备 31011702000001号 沪ICP备11019229号-2

本论坛言论纯属发表者个人意见,任何违反国家相关法律的言论,本站将协助国家相关部门追究发言者责任!     本站特聘法律顾问:李志群律师

快速回复 返回顶部 返回列表