ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

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

[原创] 不懂html也来学网抓(xmlhttp/winhttp+fiddler)

    [复制链接]

TA的精华主题

TA的得分主题

发表于 2014-10-21 11:12 | 显示全部楼层 |阅读模式
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
本帖已被收录到知识树中,索引项:网页交互
本帖最后由 wcymiss 于 2014-11-1 09:24 编辑

本帖主要针对的是不懂html的网抓新手,所以,本帖基本不谈原理,只说实战

学网抓对vba的要求:
1、了解对象及对象属性方法的基本概念;
2、熟练使用循环、判断及vba数组;
3、掌握一种以上提取文本的方法,可以在各种有规律的文本里提取所需数据;
4、会调试代码,会用立即窗口、本地窗口。(很重要,请务必学会)
5、有录制宏的经验。

可以这样说,只要你具备上述vba知识,再对网抓有点兴趣,有点耐心,那你就能学会网抓。

我本人开始用xmlhttp和fiddler的时候,对html和javascript是一窍不通的,对get、post也不懂,全是依样画葫芦。画成功后,有了兴趣,才慢慢去寻找它的原理和相关知识去学习。我想我这样的学习方法或许可以给一些像我一样的小白一个借鉴。但愿没有误导新人才好。

学习html强力推荐此网站:http://www.w3school.com.cn/ ,绝对权威

==================================================
如果发觉楼主有写错的地方,或是用错术语,或是概念模糊,或是运行出错、运行效果与楼主不同,或是有看不懂、不理解的地方,请大家及时提出来。
希望在大家的帮助和建议下完善本帖,让不会网抓的朋友由此贴学会写一些基础的网抓代码,同时感受到网抓的乐趣。

谢谢大家!



补充内容 (2014-11-5 19:37):
交流QQ群:310731499

评分

87

查看全部评分

TA的精华主题

TA的得分主题

 楼主| 发表于 2014-10-21 11:15 | 显示全部楼层
本帖最后由 wcymiss 于 2014-11-3 11:22 编辑

目录:

一、前期准备:
  1、fiddler的安装、设置、使用;
        Fiddler抓包并确认数据页面一例
  2、常用代码和自定义函数。

二、获取数据:
  1、直接获取:
    a、GET;
         作业一
    b、POST;
        作业二
    c、静态参数;
    d、转码
  2、防盗链的处理:
    a、模拟Referer;
    b、模拟Cookie;
        继续唠叨Cookie--例子暂缺
        还是Cookie-----模拟Cookie欺骗服务器一例
        作业三
    c、模拟User-Agent ;
    d、其他发包头的模拟;
    e、动态参数
      动态参数又一例
      抓取QQ群成员清单
      用IE获取Cookie

对获取数据作个小结

  3、其他
    a、缓存的困扰;
    b、重定向;
    c、代理

三、提取数据:
  1、下载文件;
  2、转码;
  3、处理数据的通用方法
  4、处理table
  5、处理xml
  6、处理JSON
    a、初识JSON
    b、JSON转换成vba对象
    c、编写JavaScript代码处理JSON(一)
    d、编写JavaScript代码处理JSON(二)
    作业四

四、发送数据
  1、登录;
    a、初识登录(以登录163邮箱为例)
    b、登录之后可以做什么----查询数据
    c、登录之后可以做什么----发送数据
    d、复杂登录前言
    e、复杂登录一:搜房网登录
    f、复杂登录二:58同城登录

  2、上传文件

点评

“Fiddler抓取法”  发表于 2014-10-23 13:02
比我习惯好,我想到哪写到哪,代码也是慢慢发展的,所以都没法事先弄个目录  发表于 2014-10-22 19:22

评分

17

查看全部评分

TA的精华主题

TA的得分主题

 楼主| 发表于 2014-10-21 11:25 | 显示全部楼层
本帖最后由 wcymiss 于 2014-10-31 10:36 编辑

vba网抓常用方法:

1、xmlhttp/winhttp法:
用xmlhttp/winhttp模拟向服务器发送请求,接收服务器返回的数据。
优点:效率高,基本无兼容性问题。
缺点:需要借助如fiddler的工具来模拟http请求。

2、IE/webbrowser法:
创建IE控件或webbrowser控件,结合htmlfile对象的方法和属性,模拟浏览器操作,获取浏览器页面的数据。
优点:这个方法可以模拟大部分的浏览器操作。所见即所得,浏览器能看到的数据就能用代码获取。
缺点:各种弹窗相当烦人,兼容性也确实是个很伤脑筋的问题。上传文件在IE里根本无法实现。(有实现方法?请一定告诉我)

3、QueryTables法:
因为它是excel自带,所以勉强也算是一种方法。其实此法和xmlhttp类似,也是GET或POST方式发送请求,然后得到服务器的response返回到单元格内。
优点:excel自带,可以通过录制宏得到代码,处理table很方便。代码简短,适合快速获取一些存在于源代码的table里的数据。
缺点:无法模拟referer等发包头(如果你有在QT中模拟referer的方法,请一定告诉我)

本帖主要讲述的是第一种方法。

评分

9

查看全部评分

TA的精华主题

TA的得分主题

 楼主| 发表于 2014-10-21 11:33 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
个人偏爱fiddler的原因:(唠叨话,可略过)

1、fiddler不需要寄生在浏览器中,且可抓到多个浏览器的包。
2、除了抓浏览器,一些联网的软件的请求数据过程也能抓到。如QQ。(据说网游也可以,不过我没试过)
3、fiddler还能记录vba代码运行时的数据请求过程。
4、界面清晰,查找数据方便。更有json、xml、javascript各种数据格式化的插件。
5、还可以手工在fiddler里模拟发包,获取数据,方便测试。

评分

8

查看全部评分

TA的精华主题

TA的得分主题

 楼主| 发表于 2014-10-21 11:45 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
fiddler的安装、设置、使用
安装:
下载链接:http://w.x.baidu.com/alading/anquan_soft_down_normal/10963安装了.Net Framework后才能安装fiddler。如果系统没有安装.Net Framework,在fiddler的安装中会提示下载安装。

设置:
1、菜单栏:Rules,勾选“Remove all Encodings”(解密所有加密数据)(很重要,否则之后会出现查找不到特征数据的情形)
2、菜单栏:Rule,勾选"Hide Image Requests"(隐藏图片包)、"Hide CONNECTs"(隐藏CONNECTs包)
fiddler设置1.png

3、菜单栏:Tools-Fidder Options-HTTPS,勾选"Capure HTTPS CONNECTs"、"Decrypt HTTPS traffic"、"Ignore server certificate
errors"。(获取https包并忽略信任错误)
fiddler设置2.png


使用:
fiddler抓包有点类似excel里的录制宏。

抓包步骤如下:
1、为确保fiddler抓到完整的数据包,抓包前请手动清除浏览器cookie、缓存及历史记录。
不要用fiddler上的按钮“Clear Cache ” ,这个按钮只能清除IE浏览器的缓存。
2、打开fiddler,然后打开浏览器,输入网址,在网页里做所需操作。操作完毕后,进入fiddler,fiddler的左半边框框内的数据就是抓到的包。为了fiddler不受之后网页操作的影响,可以点击左下方的"Capturing"按钮停止fiddler抓包。

fiddler抓包界面简单解析:
1、左边的是session框,选择该框任意一条数据,右边菜单选择“Inspectors”后出现上下两个框:上边是Request,包含所有的发送请求;下方是Response,包含所有服务器响应请求后返回的内容。
fiddler界面1.png

2、查找数据:
抓到包后,session框里的数据太多,如何找到我们需要的呢?
a、在fiddler里按ctrl+F,搜索所需某个比较有特征的数据,搜到后点击该session,Request框和Response框都选择“Raw”菜单。
搜索框内可以选择搜索范围。
fiddler搜索框.png

b、在Response框下方的空白长条框里,输入之前搜索的那个特征数据,按回车,确认其是否存在于该Response内,如果存在,再查看上下文,确认是否是所需的数据页面。
这步很重要,如果数据页面确认错了,接下来就都是做无用功了。

3、数据页面确认后,我们写代码要模拟的就是Request框中的数据。

小贴士:
特征字符尽量不要选择中文,中文可能会有转码;也尽量不要选择带格式的文本。带格式的文本通常含有html代码。这些都有可能出现搜索不到数据的情形。




补充内容 (2015-1-9 12:58):
下载链接错了,那个是下载的更新。官网下载链接是这个:http://www.telerik.com/download/fiddler/fiddler4。你也可以百度搜索下载。

点评

额,下载链接打不开,显示为:无法显示该网页  发表于 2014-11-4 14:52
,跟着贴慢慢学习吧,不做蛋糕了吗?原教程文件发我下可以不?  发表于 2014-10-23 15:51

评分

9

查看全部评分

TA的精华主题

TA的得分主题

 楼主| 发表于 2014-10-21 12:47 | 显示全部楼层
本帖最后由 wcymiss 于 2014-10-21 12:54 编辑

Fiddler抓包并确认数据页面一例:

网站:http://www.cffex.com.cn/fzjy/tjsj/pztj/
操作:点击“品种日数据统计”,在日期起始框内选择2014-10-01,在日期截止框内输入今天日期,点击“查询”,随后出现的表格为所需数据。
fiddler搜索一例.png

Fiddler操作:
1、清除浏览器cookie、缓存、历史记录。
2、打开fiddler,打开浏览器,输入网址进行操作。
3、选择数据中某一段数字作为特征字符串在fiddler里进行查找。
fiddler搜索一例2.png

fiddler搜索一例3.png

4、找到后确认是否是所需数据页面。
fiddler搜索一例4.png


IF  搜索成功 Then
     继续往下看。。。
Else
     重新按照上述步骤抓包
End IF

评分

7

查看全部评分

TA的精华主题

TA的得分主题

 楼主| 发表于 2014-10-21 12:51 | 显示全部楼层
更多Fiddler的使用方法,敬请参考《Fiddler调试权威指南》一书。
电子书下载地址:http://pan.baidu.com/s/1CRctw

我昨天才发现有这本书,赶紧收藏,还没来得及看

TA的精华主题

TA的得分主题

 楼主| 发表于 2014-10-21 13:19 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
本帖最后由 wcymiss 于 2014-11-1 16:44 编辑

常用代码及自定义函数:

1、网抓主体代码:
  1. Sub Main()
  2.     Dim strText As String
  3.     With CreateObject("MSXML2.XMLHTTP") 'CreateObject("WinHttp.WinHttpRequest.5.1")'
  4.         .Open "POST", "", False
  5.         .setRequestHeader "Content-Type", "application/x-www-form-urlencoded"
  6.         .setRequestHeader "Referer", ""
  7.         .Send
  8.         strText = .responsetext
  9.         Debug.Print strText
  10.     End With
  11. End Sub
复制代码
代码里的很多""就是留给你的填空题。。。
xmlhttp/winhttp对象的属性和方法可以网上百度学习(不学也暂时影响不大),内容不多。

2、Javascript表达式求值:
  1. Function JSEval(strText  As String) As String
  2.     With CreateObject("MSScriptControl.ScriptControl")
  3.         .Language = "javascript"
  4.         JSEval = .Eval(strText)
  5.     End With
  6. End Function
复制代码
3、url转码:
  1. Function encodeURI(strText As String) As String
  2.     With CreateObject("msscriptcontrol.scriptcontrol")
  3.         .Language = "JavaScript"
  4.         encodeURI = .Eval("encodeURIComponent('" & strText & "');")
  5.     End With
  6. End Function
复制代码
javascript提供了六个转码函数:
escape,unescape,encodeURI,encodeURIComponent,decodeURI,decodeURIComponent
具体用法请百度。我只能说我最常用的是encodeURIComponent。

4、流数据转成指定编码的文本:
  1. Function ByteToStr(arrByte, strCharset As String) As String
  2.     With CreateObject("Adodb.Stream")
  3.         .Type = 1 'adTypeBinary
  4.         .Open
  5.         .Write arrByte
  6.         .Position = 0
  7.         .Type = 2 'adTypeText
  8.         .Charset = strCharset
  9.         ByteToStr = .Readtext
  10.         .Close
  11.     End With
  12. End Function
复制代码
5、文本按指定编码转为流数据:
  1. Function StrToByte(strText As String, strCharset As String)
  2.     With CreateObject("adodb.stream")
  3.         .Mode = 3 'adModeReadWrite
  4.         .Type = 2 'adTypeText
  5.         .Charset = strCharset
  6.         .Open
  7.         .Writetext strText
  8.         .Position = 0
  9.         .Type = 1 'adTypeBinary
  10.         '.Position = 2 '保留BOM头则不需此行代码,去除三个字节的BOM头就填入3,去除两个字节的就填入2
  11.         StrToByte = .Read
  12.         .Close
  13.     End With
  14. End Function
复制代码
注:某些文本转为流后,前面会添加几个字节的BOM头,用来被某些软件识别是什么编码。如UTF-8编码的前面有三个字节的BOM头,Unicode前面有两个字节的BOM头。大家可以视情况选择保留或去除这些BOM头。
6、二进制流转成文件:
  1. Sub ByteToFile(arrByte, strFileName As String)
  2.     With CreateObject("Adodb.Stream")
  3.         .Type = 1 'adTypeBinary
  4.         .Open
  5.         .Write arrByte
  6.         .SaveToFile strFileName, 2 'adSaveCreateOverWrite
  7.         .Close
  8.     End With
  9. End Sub
复制代码
7、文本拷贝到剪贴板:
  1. Sub CopyToClipbox(strText As String)
  2.     '文本拷贝到剪贴板
  3.     With CreateObject("new:{1C3B4210-F441-11CE-B9EA-00AA006B1A69}")
  4.         .SetText strText
  5.         .PutInClipboard
  6.     End With
  7. End Sub
复制代码
先上这些,以后觉得有必要再添加

呃,原谅我吧,我是个怀旧的人。我的机器的配置目前为止仍旧是32位的winXP+2003office,IE也刚升级到IE8,之前一直用的IE6。弦月大师(xmyjk)所点评的内容我没有办法提供呀。。甩泪。。。

=================================================
突然想起HtmlWindow也可以直接执行Javascript函数得出值。
用64位office的朋友可以测试一下下面的代码能不能通过:
替代上面自定义函数2的:
  1. Function EvalByHtml(strText As String) As String
  2.     With CreateObject("htmlfile")
  3.         .write "<html><script></script></html>"
  4.         EvalByHtml = CallByName(.parentwindow, "eval", VbMethod, strText)
  5.     End With
  6. End Function
复制代码
替代上面自定义函数3的:
  1. Function encodeURIByHtml(strText As String) As String
  2.     With CreateObject("htmlfile")
  3.         .write "<html><script></script></html>"
  4.         encodeURIByHtml = CallByName(.parentwindow, "encodeURIComponent", VbMethod, strText)
  5.     End With
  6. End Function
复制代码
给Dom添加一个空的script就可以直接执行js函数了,非常好用。

为防止vba自动篡改大小写,把js函数名作为文本放在callbyname的参数里。

点评

目前很多64位的OFFICE咯,经常不支持scriptcontrol哦,要有替代方法。  发表于 2014-10-21 21:58

评分

7

查看全部评分

TA的精华主题

TA的得分主题

 楼主| 发表于 2014-10-21 14:00 | 显示全部楼层
本帖最后由 wcymiss 于 2014-10-21 21:37 编辑

获取数据-直接获取-GET

再复制一次主体代码:

  1. Sub Main()
  2.     Dim strText As String
  3.     With CreateObject("MSXML2.XMLHTTP") 'CreateObject("WinHttp.WinHttpRequest.5.1")
  4.         .Open "POST", "", False
  5.         .setRequestHeader "Content-Type", "application/x-www-form-urlencoded"
  6.         .setRequestHeader "Referer", ""
  7.         .Send
  8.         strText = .responsetext
  9.         Debug.Print strText
  10.     End With
  11. End Sub
复制代码
xmlhttp/winhttp对象的Open方法的第一参数主要有两个值:GET 和 POST。(必须大写

如何知道应该用GET还是POST呢?很简单,看之前用fiddler的数据网页的Request框Raw里的内容(仍然用8楼的例子):
GET1.png
Raw里是“GET”,所以我们代码也用“GET”,Open方法的第二参数写入GET后面的Url
后面的setRequestHeader语句暂且注释掉。
这样代码就写好了:
  1. Sub Main()
  2.     Dim strText As String
  3.     With CreateObject("MSXML2.XMLHTTP") 'CreateObject("WinHttp.WinHttpRequest.5.1")
  4.         .Open "GET", "http://www.cffex.com.cn/fzjy/tjsj/pztj/pzrtj/2014/index.xml", False
  5. '        .setRequestHeader "Content-Type", "application/x-www-form-urlencoded"
  6. '        .setRequestHeader "Referer", ""
  7.         .Send
  8.         strText = .responsetext
  9.         Debug.Print strText
  10.     End With
  11. End Sub
复制代码
运行下,查看立即窗口的结果:
GET2.png


数据成功获取。

本例是最直接的GET,不需添加setRequestHeader。

小贴士:
复制Request框内的Url时,为避免打开该链接,可以点击Request框右下角的“View in Notepad”按钮,从记事本内复制。

又:ResponseText在vba的立即窗口显示不全的原因是立即窗口只能容纳有限长度的文本。文本超长后,只能显示后面一部分的内容。

评分

8

查看全部评分

TA的精华主题

TA的得分主题

 楼主| 发表于 2014-10-21 14:13 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
本帖最后由 wcymiss 于 2014-10-22 12:35 编辑

新手作业:
1、网站:http://data.bank.hexun.com/lccp/jrxp.aspx
     操作:点击“今日在售产品”,获取今日在售产品第一页的数据。

2、网站:http://www.caac.gov.cn/S1/GNCX/
     操作:点击“查询”,获取航班信息数据。

作业说明:因为仅仅是练习fiddler的使用以及最基本网抓代码的写法,所以代码只需在ResponseText获取到所需数据就行了。不需要整理,也不必考虑动态参数的问题。

评分

3

查看全部评分

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

本版积分规则

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

GMT+8, 2024-3-29 15:43 , Processed in 0.270123 second(s), 9 queries , Gzip On, Redis On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

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

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

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