ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

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

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

    [复制链接]

TA的精华主题

TA的得分主题

发表于 2014-10-24 15:55 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
本帖已被收录到知识树中,索引项:网页交互
VBA万岁 发表于 2014-10-24 12:42
老师,我补齐了Referer,可还是报同样的错,不知为何?
我按你提供的地址下载安装了fiddler,抓包时界面 ...

经wcymiss老师的指点及onlycxb大侠的帮助,该问题已得以解决。
多谢二位,并强力支持本帖——它让我终于看到了入门的希望!

TA的精华主题

TA的得分主题

发表于 2014-10-24 21:07 | 显示全部楼层
本帖最后由 renahu 于 2014-10-24 22:42 编辑
VBA万岁 发表于 2014-10-22 12:32
接续onlycxb大侠的代码,完成另一半:
Sub HomerWork1_1()
Dim xml As New MSXML2.XMLHTTP, url As Str ...


我把这段代码拷贝到我的模块里,怎么总提示: 用户定义类型未定义  Dim xml As New MSXML2.XMLHTTP   


明白了,要引用

TA的精华主题

TA的得分主题

发表于 2014-10-24 22:48 | 显示全部楼层
VBA万岁 发表于 2014-10-23 15:12
百度结果:
http://zhidao.baidu.com/link?url=-9S1gJlPKiBWbC-e_wBQ8lQUI409P4xuGZ-wtvLjLUZzvwEyDNbpF ...

说好的clearmytrackbyprocess呢= =!

TA的精华主题

TA的得分主题

发表于 2014-10-25 08:49 | 显示全部楼层
本帖最后由 onlycxb 于 2014-10-25 13:04 编辑
renahu 发表于 2014-10-24 21:07
我把这段代码拷贝到我的模块里,怎么总提示: 用户定义类型未定义  Dim xml As New MSXML2.XMLHTTP   
...

我喜欢前期绑定,这样会有提示。对于记忆不太好的我来讲。可以充分利用智能提示来完成代码的准确编写,而不是copy改。

TA的精华主题

TA的得分主题

 楼主| 发表于 2014-10-25 09:05 | 显示全部楼层
本帖最后由 wcymiss 于 2014-10-26 10:10 编辑

处理数据的通用方法

1、数组法:
   用split和数组,循环将所需数据取出。
   优点:不需其他对象辅助,起点低,会数组即可。
   缺点:需要分析数据结构,对于复杂结构的数据,需要多步才能完成。
   以作业一的第1题为例:
  1. Sub Main()
  2.     Dim strText As String
  3.     Dim arrRow, arrCell
  4.     Dim i As Long, j As Long, n As Long
  5.     Dim arrColumn
  6.     Dim arrData(1 To 1000, 1 To 10)
  7.    
  8.     With CreateObject("MSXML2.XMLHTTP")
  9.         .Open "GET", "http://data.bank.hexun.com/lccp/jrxp.aspx", False
  10.         .Send
  11.         strText = .responsetext
  12.     End With
  13.    
  14.     arrColumn = Array(, , 9, 12, 14, 16, 18, 20, 22, 24, 26)
  15.     arrRow = Split(strText, "name='proTest' ")
  16.     For i = 1 To UBound(arrRow)
  17.         arrCell = Split(arrRow(i), ">")
  18.         n = n + 1
  19.         arrData(n, 1) = Split(Split(arrCell(0), "value='")(1), "'")(0)
  20.         For j = 2 To 10
  21.             arrData(n, j) = Split(arrCell(arrColumn(j)), "<")(0)
  22.         Next
  23.     Next
  24.    
  25.     Cells.Clear
  26.     Range("a1:j1").Value = Split("产品名称 是否在售 银行 起售日 停售日 币种 管理期(月) 产品类型 预期收益(%) 收益类型", " ")
  27.     Range("a2").Resize(n, 10).Value = arrData
  28. End Sub
复制代码
2、正则法:
   用正则拆解字符串,提取匹配数据,循环取出。
   优点:即便复杂结构的数据,也有可能一步到位。
   缺点:需要学习正则知识。
   70楼获取到QQ群成员清单后,用正则提取成员的昵称和QQ号:
   
  1. Sub Main()
  2.     Const gc As String = "" '群号
  3.     Const bkn As String = "" '从fiddler中获取
  4.     Const uin As String = "" 'QQ号
  5.     Const skey As String = "" '从fiddler中获取
  6.     Dim strText As String
  7.     Dim RegMatch As Object
  8.     Dim arrData(1 To 1000, 1 To 2)
  9.     Dim n As Long
  10.    
  11.     With CreateObject("WinHttp.WinHttpRequest.5.1")
  12.         .Open "GET", "http://qinfo.clt.qq.com/cgi-bin/qun_info/get_group_members_new?gc=" & gc & "&bkn=" & bkn, False
  13.         .setRequestHeader "Cookie", "uin=o" & uin & "; skey=" & skey
  14.         .Send
  15.         strText = .responsetext
  16.         Debug.Print strText
  17.     End With
  18.    
  19.     With CreateObject("VBScript.Regexp")
  20.         .Global = True
  21.         .Pattern = "{""b"":\d+,""g"":\d+,""n"":""([^""]*)"",""u"":(\d+)}"
  22.         For Each RegMatch In .Execute(strText)
  23.             n = n + 1
  24.             arrData(n, 1) = RegMatch.submatches(0)
  25.             arrData(n, 2) = RegMatch.submatches(1)
  26.         Next
  27.     End With
  28.    
  29.     Set RegMatch = Nothing
  30.     Cells.Clear
  31.     Range("a1:b1").Value = Array("昵称", "QQ号")
  32.     Range("a2").Resize(n, 2).Value = arrData
  33. End Sub
复制代码


以上两种方法对于处理获取到的数据一般都能用,但都需先行分析获数据结构。对于复杂结构数据,需要时间和耐心。

table、xml、json各自还有一些专用的提取方法。

评分

1

查看全部评分

TA的精华主题

TA的得分主题

发表于 2014-10-25 09:06 | 显示全部楼层
onlycxb 发表于 2014-10-25 08:49
我喜欢前期绑定,这样会有提示。对于忘记不太好的我来讲。可以充分利用智能提示来完成代码的准确编写,而 ...

呵呵,我跟您没法比,我是纯菜鸟,真心不知道什么是前期绑定,您能否告知这个例子如何做前期绑定吗?谢谢

TA的精华主题

TA的得分主题

发表于 2014-10-25 09:41 | 显示全部楼层

TA的精华主题

TA的得分主题

发表于 2014-10-25 10:19 | 显示全部楼层
本帖最后由 onlycxb 于 2014-10-25 10:31 编辑
renahu 发表于 2014-10-25 09:06
呵呵,我跟您没法比,我是纯菜鸟,真心不知道什么是前期绑定,您能否告知这个例子如何做前期绑定吗?谢谢

前期绑定就是先引用相关库。比如MSXML2.XMLHTTP
前期绑定方式步骤:在VBE编辑器中,选择工具栏  >工具>引用,将弹出引用对话框
前期绑定.png
在代码中利用实例化对象即可。详细看GIf录制
a21.gif

利用前期绑定后的代码如下:
Sub Test()
    Dim xml As New MSXML2.XMLHTTP
    With xml
    .Open "GET", URL, False
    .send
    End With
End Sub
稍加修改,即可变为后期绑定
Sub Test()
    Dim xml As Object                                          '原代码xml As New MSXML2.XMLHTTP
    Set xml = CreateObject("MSXML2.XMLHTTP") '这句是后期绑定语句
    With xml
      .Open "GET", URL, False
      .send
    End With
End Sub



评分

1

查看全部评分

TA的精华主题

TA的得分主题

 楼主| 发表于 2014-10-25 10:43 | 显示全部楼层
本帖最后由 wcymiss 于 2014-10-27 13:07 编辑

处理table
table数据处理,除了之前的两种通用方法外,还有以下几种方法:

1、html法
   将table数据写入htmldocument对象,然后循环取出表格的各个元素。
   优点:可以利用htmldocument对象整理表格。
   缺点:需要学习html相关知识。
   以17楼作业二为例:
  1. Sub Main()
  2.     Dim strText As String
  3.     Dim arrData(1 To 1000, 1 To 3)
  4.     Dim i As Long, j As Long
  5.     Dim TR As Object, TD As Object
  6.    
  7.     With CreateObject("MSXML2.XMLHTTP")
  8.         .Open "POST", "http://www.pinble.com/Template/WebService1.asmx/Present3DList", False
  9.         .setRequestHeader "Content-Type", "application/json"
  10.         .Send "{pageindex:'1',lottory:'TC7XCData_jiangS',pl3:'',name:'江苏七星彩',isgp: '0'}"
  11.         strText = Split(JSEval(.responsetext), "<script")(0) '本例的script运行会提示错误,所以去除这部分script代码
  12.     End With
  13.    
  14.     With CreateObject("htmlfile")
  15.         .write strText
  16.         i = 0
  17.         For Each TR In .all.tags("table")(2).Rows
  18.             i = i + 1
  19.             j = 0
  20.             For Each TD In TR.Cells
  21.                 j = j + 1
  22.                 arrData(i, j) = TD.innerText
  23.             Next
  24.         Next
  25.     End With
  26.    
  27.     Set TR = Nothing
  28.     Set TD = Nothing
  29.     Cells.Clear
  30.     Range("C:C").NumberFormat = "@" '设置文本格式以显示数字前面的0
  31.     Range("a1").Resize(i, 3).Value = arrData
  32. End Sub

  33. Function JSEval(s As String) As String
  34.     With CreateObject("MSScriptControl.ScriptControl")
  35.         .Language = "javascript"
  36.         JSEval = .Eval(s)
  37.     End With
  38. End Function
复制代码
2、QueryTable法:
   这个是excel自带的网抓利器。个人觉得它最大的优势就是处理table很方便。
   优点:处理table方便,代码简短。
   缺点:会产生定义名称。多页循环时每页都会产生行字段名称,需要后续处理删除。
   仍以作业一的第1题为例:
  1. Sub Main()
  2.     Cells.Delete
  3.     With ActiveSheet.QueryTables.Add("url;http://data.bank.hexun.com/lccp/jrxp.aspx", Range("a1"))
  4.         .WebFormatting = xlWebFormattingNone '不包含格式
  5.         .WebSelectionType = xlSpecifiedTables '指定table模式
  6.         .WebTables = "2" '第2张table
  7.         .Refresh False
  8.     End With
  9. End Sub
复制代码
代码相当简短。


3、复制粘贴法:
   table部分的文字可以直接复制到单元格内,且保留数据原格式。
   优点:只需取出table部分,不需分析数据内部结构。代码编写简便。
   缺点:有时格式反而是累赘。
  1. Sub Main()
  2.     Dim strText As String
  3.     With CreateObject("MSXML2.XMLHTTP")
  4.         .Open "GET", "http://data.bank.hexun.com/lccp/jrxp.aspx", False
  5.         .Send
  6.         strText = .responsetext
  7.     End With
  8.     strText = "<table" & Split(Split(strText, "<table")(2), "</table>")(0) & "</table>"
  9.     CopyToClipbox strText
  10.     Cells.Clear
  11.     Range("a1").Select
  12.     ActiveSheet.Paste
  13. End Sub

  14. Sub CopyToClipbox(strText As String)
  15.     '文本拷贝到剪贴板
  16.     With CreateObject("new:{1C3B4210-F441-11CE-B9EA-00AA006B1A69}")
  17.         .SetText strText
  18.         .PutInClipboard
  19.     End With
  20. End Sub
复制代码
小贴士:
点击Fiddler的Response框的WebView按钮可以看到HTML代码在网页上的显示效果。

评分

9

查看全部评分

TA的精华主题

TA的得分主题

发表于 2014-10-25 11:11 | 显示全部楼层
wcymiss 发表于 2014-10-25 10:43
处理table

table数据处理,除了之前的两种通用方法外,还有以下几种方法:

With CreateObject("htmlfile")
        .write strText
        i = 0
        For Each TR In .all.tags("table")(2).Rows
            i = i + 1
            j = 0
            For Each TD In TR.Cells
                j = j + 1
                arrData(i, j) = TD.innerText
            Next
        Next
    End With
上述代码提取数据简单,此表有
<table id="MyGridView" cellspacing="0" cellpadding="0" bordercolor="#B6CBE8" border="1" style="width: 100%; border-collapse: collapse;" rules="all">
<tbody>
利用如下语句也可实现
For Each TR In .all.tags("table")("MyGridView").Rows


评分

1

查看全部评分

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

本版积分规则

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

GMT+8, 2024-12-23 02:31 , Processed in 0.039689 second(s), 8 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

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

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

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