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-23 16:12 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
本帖已被收录到知识树中,索引项:网页交互
本帖最后由 wcymiss 于 2014-10-30 18:19 编辑

缓存的困扰
用xmlhttp对象GET数据时,会优先从缓存中调取。

比如下面这段代码:
  1. Sub Main()
  2.     Dim strText As String
  3.     With CreateObject("MSXML2.XMLHTTP")
  4.         .Open "GET", "http://www.1396me.com/shishicai/", False
  5.         .Send
  6.         strText = .responsetext
  7.         Debug.Print "最新开奖期数:"; Left(Split(strText, "<p class=""p"">")(1), 12)
  8.         Debug.Print "最新开奖时间:"; Left(Split(strText, "<p class=""t"">")(1), 5)
  9.     End With
  10. End Sub
复制代码
运行后,不要关闭该excel,过10分钟再运行,仍然出现之前的结果,数据没有更新。但网页上已有更新。

这种现象是因为xmlhttp调用了缓存的数据。

这个缓存不是指浏览器的缓存,而是excel的缓存。不信你清除浏览器的缓存试试,代码结果仍然不会更新。

这个缓存随excel的进程结束而消失。

所以我们在网抓的调试中,为了验证一段代码能否真正获取到数据,除了清除浏览器的Cookie缓存种种,还必须关闭excel再重新打开excel后再运行代码。这时的运行结果才是代码的真正结果。

那么,除了关闭excel,有没有其他方法能避免这样的现象呢?

回答当然是“有”,而且有多种方法可以避免xmlhttp调用缓存的数据。

方法如下:

1、在URL后面添加随机参数。
   比如上述代码中,我们把Open语句改成:
   .Open "GET", "http://www.1396me.com/shishicai/?=" & Rnd(), False   然后代码就能实时更新了。

   这个方法最简单,但它未必对所有的网页适用。

2、添加setRequestHeader
   在代码的Send语句前加一句:
   .setRequestHeader "If-Modified-Since", "0"
   这句语句的具体含义请百度。在这里我们用它使代码效果实时更新。
   同样,未必对所有的网页都适用,而且效率比上种方法低下。

3、用winhttp代替xmlhttp
   winhttp不会从缓存中调取数据。

点评

就是winhttp被释放掉就没缓存,如果持续运行时,依然有缓存的。  发表于 2014-10-24 21:32
ServerXMLHTTP 依赖于 HTTP 客户端堆栈 WinHTTP,按demon意思,winhttp也是有缓存的。缓存也分为会话型和持久型,winhttp是不支持持久的,但依然支持会话型的缓存。  发表于 2014-10-24 21:30
winhttp有缓存的,http://demon.tw/programming/msxml2-xmlhttp-msxml2-serverxmlhttp-cache-again.html  发表于 2014-10-24 21:28
我也遇到了这个问题,及时雨啊,吴姐太伟大了  发表于 2014-10-23 16:40

评分

4

查看全部评分

TA的精华主题

TA的得分主题

发表于 2014-10-23 16:24 | 显示全部楼层
不好意思,關於34樓的單獨拿取COOKIE那個練習,我不能單獨取出COOKIE來,請問有什麼問題呢?

点评

“不能”是什么意思?无法复制吗?  发表于 2014-10-23 16:29

TA的精华主题

TA的得分主题

发表于 2014-10-23 16:26 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
必须马住!

TA的精华主题

TA的得分主题

发表于 2014-10-23 16:39 | 显示全部楼层
wcymiss 发表于 2014-10-21 15:20
新手作业:
网站:http://www.pinble.com/Lottery.htm
操作:点击“各省体彩”---“江苏七星彩”,获取江 ...

新手作业
  1. Sub 江苏七星彩()
  2.     Dim objhq As New WinHttp.WinHttpRequest
  3.     Dim STxt As String, Url As String, i As Integer, j As Integer
  4.     Dim Pages As Integer, Pstr As String, arr, brr, rng As Range
  5.     Cells.Clear
  6.     With objhq
  7.         .Open "POST", "http://www.pinble.com/Template/WebService1.asmx/Present3DList", False
  8.         .SetRequestHeader "Content-Type", "application/json; charset=UTF-8"
  9.         .SetRequestHeader "Referer", "http://www.pinble.com/Lottery.htm"
  10.         .Send "{pageindex:'1',lottory:'TC7XCData_jiangS',pl3:'',name:'江苏七星彩',isgp: '0'}"
  11.         STxt = .ResponseText
  12.     End With
  13.     STxt = UTF8toChineseCharacters(STxt)                                                           'J3编码
  14.     Pages = Split(Split(Split(STxt, "分页")(1), "页")(0), "/")(1)

  15.     '循环各页取数,下面以取2页为例 ,实际总页数Pages
  16.     For i = 1 To 2
  17.         With objhq
  18.             .Open "POST", "http://www.pinble.com/Template/WebService1.asmx/Present3DList", False
  19.             .SetRequestHeader "Content-Type", "application/json; charset=UTF-8"
  20.             .SetRequestHeader "Referer", "http://www.pinble.com/Lottery.htm"
  21.             .Send "{pageindex:'" & i & "',lottory:'TC7XCData_jiangS',pl3:'',name:'江苏七星彩',isgp: '0'}"
  22.             STxt = UTF8toChineseCharacters(.ResponseText)
  23.         End With

  24.         Cells(1, 1) = "江苏七星彩 开奖信息": Cells(1, 2) = "开奖周期:周二、周四、周五、周日"
  25.         Cells(2, 1).Resize(1, 3) = Array("开奖时间", "期号", "开奖号码")
  26.         Pstr = "<tr style='backgro%und-color: White; border-color: #B6CBE8;'>"
  27.         arr = Split(STxt, Pstr)
  28.         ReDim brr(1 To UBound(arr) - 1, 1 To 3)
  29.         For j = 1 To UBound(arr) - 1
  30.             brr(j, 1) = Split(Split(arr(j), "</td>")(0), ">")(1)
  31.             brr(j, 2) = Split(Split(arr(j), "</td>")(1), ">")(1)
  32.             brr(j, 3) = Split(Split(Split(arr(j), "</td>")(2), "</span>")(0), "ctl02_lblHao'>")(1)
  33.         Next j
  34.         Set rng = Cells(Rows.Count, 1).End(xlUp).Offset(1, 0)
  35.         rng.Resize(UBound(brr, 1), 3) = brr
  36.     Next i
  37.     Columns("A:A").NumberFormatLocal = "yyyy-m-d"
  38.     Columns("B:C").NumberFormatLocal = "@"
  39.     Columns("A:C").EntireColumn.AutoFit
  40. End Sub
  41. Function UTF8toChineseCharacters(szInput)
  42.     With CreateObject("MSScriptControl.ScriptControl")
  43.     .Language = "JavaScript"
  44.     .AddCode "function decode(str){return unescape(str.replace(/\u/g,'%u'));}"
  45.     UTF8toChineseCharacters = .Eval("decode('" & szInput & "')")
  46.     End With
  47. End Function
复制代码

补充内容 (2014-11-1 17:50):
\u是J3

点评

呃,还真没注意你这个自定义函数的名字里的歧义。。\uxxxx不是utf-8 。。。  发表于 2014-11-1 13:34

TA的精华主题

TA的得分主题

发表于 2014-10-23 16:44 | 显示全部楼层
wcymiss 发表于 2014-10-21 15:20
新手作业:
网站:http://www.pinble.com/Lottery.htm
操作:点击“各省体彩”---“江苏七星彩”,获取江 ...

新手作业
  1. Sub 江苏七星彩()
  2.     Dim objhq As New WinHttp.WinHttpRequest
  3.     Dim STxt As String, Url As String, i As Integer, j As Integer
  4.     Dim Pages As Integer, Pstr As String, arr, brr, rng As Range
  5.     Cells.Clear
  6.     With objhq
  7.         .Open "POST", "http://www.pinble.com/Template/WebService1.asmx/Present3DList", False
  8.         .SetRequestHeader "Content-Type", "application/json; charset=UTF-8"
  9.         .SetRequestHeader "Referer", "http://www.pinble.com/Lottery.htm"
  10.         .Send "{pageindex:'1',lottory:'TC7XCData_jiangS',pl3:'',name:'江苏七星彩',isgp: '0'}"
  11.         STxt = .ResponseText
  12.     End With
  13.     STxt = UTF8toChineseCharacters(STxt)                                                           'J3编码
  14.     Pages = Split(Split(Split(STxt, "分页")(1), "页")(0), "/")(1)

  15.     '循环各页取数,下面以取2页为例 ,实际总页数Pages
  16.     For i = 1 To 2
  17.         With objhq
  18.             .Open "POST", "http://www.pinble.com/Template/WebService1.asmx/Present3DList", False
  19.             .SetRequestHeader "Content-Type", "application/json; charset=UTF-8"
  20.             .SetRequestHeader "Referer", "http://www.pinble.com/Lottery.htm"
  21.             .Send "{pageindex:'" & i & "',lottory:'TC7XCData_jiangS',pl3:'',name:'江苏七星彩',isgp: '0'}"
  22.             STxt = UTF8toChineseCharacters(.ResponseText)
  23.         End With

  24.         Cells(1, 1) = "江苏七星彩 开奖信息": Cells(1, 2) = "开奖周期:周二、周四、周五、周日"
  25.         Cells(2, 1).Resize(1, 3) = Array("开奖时间", "期号", "开奖号码")
  26.         Pstr = "<tr style='backgro%und-color: White; border-color: #B6CBE8;'>"
  27.         arr = Split(STxt, Pstr)
  28.         ReDim brr(1 To UBound(arr) - 1, 1 To 3)
  29.         For j = 1 To UBound(arr) - 1
  30.             brr(j, 1) = Split(Split(arr(j), "</td>")(0), ">")(1)
  31.             brr(j, 2) = Split(Split(arr(j), "</td>")(1), ">")(1)
  32.             brr(j, 3) = Split(Split(Split(arr(j), "</td>")(2), "</span>")(0), "ctl02_lblHao'>")(1)
  33.         Next j
  34.         Set rng = Cells(Rows.Count, 1).End(xlUp).Offset(1, 0)
  35.         rng.Resize(UBound(brr, 1), 3) = brr
  36.     Next i
  37.     Columns("A:A").NumberFormatLocal = "yyyy-m-d"
  38.     Columns("B:C").NumberFormatLocal = "@"
  39.     Columns("A:C").EntireColumn.AutoFit
  40. End Sub
  41. Function UTF8toChineseCharacters(szInput)
  42.     With CreateObject("MSScriptControl.ScriptControl")
  43.     .Language = "JavaScript"
  44.     .AddCode "function decode(str){return unescape(str.replace(/\u/g,'%u'));}"
  45.     UTF8toChineseCharacters = .Eval("decode('" & szInput & "')")
  46.     End With
  47. End Function
复制代码

TA的精华主题

TA的得分主题

发表于 2014-10-23 16:46 | 显示全部楼层

TA的精华主题

TA的得分主题

发表于 2014-10-23 16:59 | 显示全部楼层
VBA万岁 发表于 2014-10-22 12:33
ie法完成作业1:
Sub 今日在售银行产品()
'On Error Resume Next

这个怎么提示“445”错误,说对象不支持该动作

TA的精华主题

TA的得分主题

发表于 2014-10-23 17:22 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
renahu 发表于 2014-10-23 16:59
这个怎么提示“445”错误,说对象不支持该动作

将'On Error Resume Next
前面的逗号去掉看看。

TA的精华主题

TA的得分主题

发表于 2014-10-23 17:24 | 显示全部楼层
wcymiss 发表于 2014-10-23 16:12
缓存的困扰
用xmlhttp对象GET数据时,会优先从缓存中调取。

明天继续学习......

TA的精华主题

TA的得分主题

发表于 2014-10-23 17:49 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
blanksoul12 发表于 2014-10-23 16:24
不好意思,關於34樓的單獨拿取COOKIE那個練習,我不能單獨取出COOKIE來,請問有什麼問題呢?


在34樓第三點時,運行到 Debug.Print strText 這句後看即時窗時,只發現
Date: Thu, 23 Oct 2014 09:41:30 GMT
Transfer-Encoding: chunked
Content-Type: text/html;charset=UTF-8
Server: Apache-Coyote/1.1
所以到之後這句 strCookie = Split(Split(strText, "JSESSIONID=")(1), ";")(0) 時便出現 ERROR 了

点评

呃,原来是我的问题。。http://club.excelhome.net/forum.php?mod=redirect&goto=findpost&ptid=1159783&pid=7909618  发表于 2014-10-24 15:03
你是不是用错了对象?应该用winhttp。我红字特地说了的。  发表于 2014-10-23 19:54
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

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

GMT+8, 2024-11-14 14:36 , Processed in 0.042064 second(s), 6 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

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

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

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