ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

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

[原创] VBA网页爬虫和多线程指南

  [复制链接]

TA的精华主题

TA的得分主题

发表于 2018-2-22 11:27 | 显示全部楼层 |阅读模式
本帖最后由 wolfccb 于 2018-2-22 17:43 编辑

如果你能点进这篇文章,那我们一定是同道中人,我就开门见山直奔主题了。此文将概述VBA爬虫从简单实现到多线程的各种主要思路。需要你有一点VBA和网络前端基础。

本文的代码均在WPS的ET表格下测试通过,Office Excel应该也没有兼容性问题。是为“孙悟空”系列爬虫的独家秘笈。

无标题.jpg

内容提要
  • VBA爬取网页的方式
  • 解决登录问题
  • 利用异步加快速度
  • 看似不可能的多线程实现
  • 总结


代码就不在这发了,方便阅读的版本和源代码请看http://wolfccb.com/?p=647

1. VBA爬取网页的方式
简单来说,常用的思路有两种:

1.1 使用Webbrowser控件
相当于在Office里打开一个看得见的IE。优点是实现简单,易于调试,整个抓取过程直观可视,易于解决动态网页、跨域登录等棘手问题。缺点是不灵活,有些网页处理不了;还有就是速度慢,很慢,毕竟除了通信之外还需要IE来渲染网页。

1.2 使用XMLhttp对象
优点是速度快,灵活,可以实现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解析、保存附件等等。有时为了避免被网站封杀,还要加上一些延时。具体问题只能在抓取过程中各个击破。祝各位好运。

以上。
搞定搞不定的老狼

评分

9

查看全部评分

TA的精华主题

TA的得分主题

发表于 2018-2-22 11:53 | 显示全部楼层

TA的精华主题

TA的得分主题

发表于 2018-2-22 12:10 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
收藏留存,谢谢lz

TA的精华主题

TA的得分主题

发表于 2018-2-22 15:44 | 显示全部楼层

TA的精华主题

TA的得分主题

发表于 2018-2-22 15:59 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
厉害!!!!!!!!!!!

TA的精华主题

TA的得分主题

 楼主| 发表于 2018-2-22 17:50 | 显示全部楼层
不能添加外链,是因为我的级别太低吗?

以上。
挠头的老狼

TA的精华主题

TA的得分主题

发表于 2018-2-22 18:09 | 显示全部楼层

TA的精华主题

TA的得分主题

发表于 2018-2-22 19:43 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
顶,支持楼主!

TA的精华主题

TA的得分主题

发表于 2018-2-22 21:18 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
厉害,但是看过用python做的爬虫更简单和高效

TA的精华主题

TA的得分主题

发表于 2018-2-23 01:12 | 显示全部楼层
我测试过,使用winhttp一次发送800个异步链接请求是可以的,如果你只能发20个,速度上不去,应该是其它原因,具体百度会告诉你答案。
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

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

GMT+8, 2024-5-6 08:11 , Processed in 0.037955 second(s), 13 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

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

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

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