VBA网页爬虫和多线程指南
优采云 发布时间: 2022-05-07 20:45VBA网页爬虫和多线程指南
优点是速度快,灵活,可以实现GET、POST、Header、Cookie等诸多细节。缺点是比Webbrowser麻烦一点,调试不直观。为了方便引用网页中的信息,不妨把XMLhttp的responsetext装进一个HTMLfile对象,就可以像Webbrowser一样检索了。
2. 解决登录问题
用Click模拟登录比把用户名、密码写在url里或者send请求来的简单,通用性也更好。尤其是有些网站的表单submit时要执行额外的script,或者登录时要跨域发送登录信息。
如果遇到跨域登录或者iframe的情况,参照所附代码最后一段:Click之后等待最终的登录返回页面,而不是等待登录页加载完毕。
如果使用XMLhttp发送登录请求遇到登录问题,建议就不要费力气琢磨什么伪造Cookie了,使用Webbrowser来登录吧,登录后同一个Excel进程里的所有XMLhttp和Webbrowser都会共享到这个登录信息,特别省心。
使用Set oIE = CreateObject("internetexplorer.application")不能和Webbrowser以及XMLhttp互相共享登录信息,Winhttp似乎也不能。
3. 利用异步加快速度
一个一个等待网页返回太慢,所以我们不用同步方式send一个等待一个,而是用异步,一次send一批请求出去,统一等待。初衷当然很好,然而VBA不支持多线程,所以这里的速度提高比较有限,一次发送20个请求大概只能提速2倍。再多似乎没什么用了。nThread值的选择在很大程度上于所爬网站的速度,建议多次测试决定。
4. 看似不可能的多线程实现
也许有很多人跟你说过VBA不支持多线程。没错,它确实不支持,用API极其麻烦而且不稳定。但是,Windows操作系统支持多线程,我们就利用这一点来绕开VBA的限制。不光有办法,而且有三种。
4.1 利用VBScript加Application
将含有宏的工作簿另存n份,生成n个VBScript脚本文件,每个脚本用Excel.Application对象打开一个工作簿,运行每个工作簿里的VBA爬虫,将爬到的结果统一写回主Excel里。这种方式有两个好处:一是用字符串的VBScript代码比较简洁,二是每个线程都可以利用Webbrowser控件方便地登录。缺点就是打开一批Excel导致系统负担较重。searchWorker过程里创建了一个Excel对象,通过工作簿名称workbookName将爬到的数据写回原工作簿。
4.2 只用VBScript实现多线程
有了上一节的示例,很容易就可以构造出合适的VBScript文件,并且在文件里直接抓取数据,代码我就不放了。比起VBScript加Application的方法,只用VBScript拼字符串写起来更麻烦,但程序执行起来非常轻量级,所以如果你要抓取的网站没有复杂的登录过程,又不怕代码麻烦,那么可以考虑用VBScript。示例可以在Excelhero找到,代码相当乱而且长。
4.3 使用ActiveX EXE实现多线程
这个有前人写过,优点是资源消耗适中,缺点是需要有Visual Basic环境,实现起来也更复杂,可在excelhome找到。
5. 总结
我个人推荐VBScript加Application的多线程方案,通用性更强,而且现在的电脑已经不太在乎多占些内存了。比起本文前面使用XMLhttp批量异步发送的方法,VBS+Application的方案创建8个线程可以提速5倍左右,效率很高。测试电脑是4核心8线程的i7台式机,8G内存。爬虫网抓时,每个WPS ET线程大概占用不到100M内存,机器完全可以承受。
做爬虫可能会遇到很多问题,比如翻页、动态网页、json解析、保存附件等等。有时为了避免被网站封杀,还要加上一些延时。具体问题只能在抓取过程中各个击破。祝各位好运。
以上。
搞定搞不定的老狼