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-11-16 22:05 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
本帖已被收录到知识树中,索引项:网页交互
VBA万岁 发表于 2014-11-14 15:46
老师,我用你的代码(用户名及密码需改为自已的)运行后,登陆成功,接着进入依次进入“个人帐户”-“我的 ...

经过多次测试,发现也不是漏了两个参数的问题,是登录网站进行查询时,需要设置下发送头里的cookie。

代码如下:
  1. Sub Main()
  2.     Const UserName As String = "vbatest" '假设的账户
  3.     Const UserPwd As String = "12341234"
  4.     Dim strText As String
  5.     Dim strJS As String
  6.     Dim strJSFun As String
  7.     Dim pwdRtn As String
  8.     Dim strCookie As String
  9.     Dim Temp, i As Integer
  10.    
  11.     With CreateObject("WinHttp.WinHttpRequest.5.1")
  12.         '1、获取js文件的js代码:
  13.         .Open "GET", "http://img1.soufun.com/secondhouse/image/magent/js/RSA.js", False
  14.         .Send
  15.         strJS = .responsetext
  16.         .Open "GET", "http://img1.soufun.com/secondhouse/image/magent/js/BigInt.js", False
  17.         .Send
  18.         strJS = strJS & ";" & .responsetext
  19.         .Open "GET", "http://img1.soufun.com/secondhouse/image/magent/js/Barrett.js", False
  20.         .Send
  21.         strJS = strJS & ";" & .responsetext
  22.         
  23.         '2、截取函数cmdEncrypt的执行语句,并把获取str_userpwd文本框的值的代码替换为我们的密码变量。
  24.         .Open "GET", "http://agent.fang.com/", False
  25.         .Send
  26.         strText = .responsetext
  27.         strJSFun = Mid(strText, InStr(strText, "setMaxDigits("))
  28.         strJSFun = Left(strJSFun, InStr(strJSFun, "$(""#str_userpwd"").attr(""value"", pwdRtn);") - 1)
  29.         strJSFun = Replace(strJSFun, "$(""#str_userpwd"").attr(""value"")", "'" & UserPwd & "'")
  30.         
  31.         '3、将strJS和strJSFun结合后执行,取出pwdRtn值:
  32.         pwdRtn = JSEval(strJS & ";" & strJSFun & ";pwdRtn")
  33.         
  34.         '4、登录
  35.         .Open "POST", "http://agent.soufun.com/DealCenterLogin.aspx?codev=" & Round(Rnd() * 10000), False
  36.         .setRequestHeader "Content-Type", "application/x-www-form-urlencoded"
  37.         .Send "str_username=" & UserName & "&str_userpwd=" & pwdRtn & "&Submit1=%B5%C7++%C2%BC"
  38. '        Debug.Print .getallresponseheaders '有三个Set-Cookie表明登录成功
  39.         
  40.         '5、获取Cookie
  41.         Temp = Split(.getallresponseheaders, "Set-Cookie: ")
  42.         Temp(0) = ""
  43.         For i = 1 To UBound(Temp)
  44.             Temp(i) = Split(Temp(i), ";")(0)
  45.         Next
  46.         strCookie = Mid(Join(Temp, ";"), 2)
  47.         If strCookie = "" Then MsgBox "登录失败!请检查账户密码是否正确": Exit Sub
  48.         
  49.         '6、验证登录
  50.         .Open "GET", "http://n.agent.fang.com/Magent/Agent/agentinfo/ModifyAgent1.aspx", False
  51.         .setRequestHeader "Cookie", strCookie
  52.         .Send
  53.         Debug.Print .responsetext
  54.     End With
  55. End Sub

  56. Function JSEval(s As String) As String
  57.     With CreateObject("MSScriptControl.ScriptControl")
  58.         .Language = "javascript"
  59.         JSEval = .Eval(s)
  60.     End With
  61. End Function
复制代码
之前的帖子也不麻烦版主编辑了,反正之前的代码主要目的是加密参数的演示。基本不受影响。我再稍作点补充就是。

PS:获取header里的cookie必须要用winhttp。xmlhttp获取的不完全。(httponly的就获取不到,和IE还真是弟兄俩)

TA的精华主题

TA的得分主题

发表于 2014-11-17 11:14 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
wcymiss 发表于 2014-11-16 22:05
经过多次测试,发现也不是漏了两个参数的问题,是登录网站进行查询时,需要设置下发送头里的cookie。

...

多谢老师!
不过我这里测试还是不成功:
首先,第46句是否应改为如下:
strCookie = Mid(Join(Temp, ";"), 2, Len(Join(Temp, ";")) - 1)
但,即使作如上更改后,测试仍不成功——虽登录成功但仍取不到数,如下截图:

TA的精华主题

TA的得分主题

 楼主| 发表于 2014-11-17 14:55 | 显示全部楼层
本帖最后由 wcymiss 于 2014-11-17 14:58 编辑
VBA万岁 发表于 2014-11-17 11:14
多谢老师!
不过我这里测试还是不成功:
首先,第46句是否应改为如下:


立即窗口显示的不全而已。你看前5000个字符就有信息了。Debug.Print Left(.responsetext, 5000)

如果获取信息不成功的话,立即窗口会返回“..............alert('请先登录!')..........”这样的字样

mid可以省略第三参数的。省略时默认为取到最后一个字符。这个帮助里有写的。

评分

1

查看全部评分

TA的精华主题

TA的得分主题

发表于 2014-11-17 15:59 | 显示全部楼层
wcymiss 发表于 2014-11-17 14:55
立即窗口显示的不全而已。你看前5000个字符就有信息了。Debug.Print Left(.responsetext, 5000)

如果 ...

果真如此,多谢!!!

TA的精华主题

TA的得分主题

发表于 2014-11-17 23:09 | 显示全部楼层
本帖最后由 onthetrip 于 2014-11-17 23:14 编辑
wcymiss 发表于 2014-11-1 17:13
上传文件
同样,上传文件也可以用fiddler抓包。

吴姐,我在公司内网上传文件发送邮件不能成功,麻烦您有空帮我看一下,谢谢先
手工操作步骤是这样的:
1/打开浏览器,输入网址,填入用户名,密码,附加码,登录
2/点击发送邮件
3/写入收件人名称
4/浏览附件
5/点击发送邮件
我在Fiddler中搜寻到了“2014年试考核”这个邮件附件所在的session,request框数据:

TA的精华主题

TA的得分主题

发表于 2014-11-17 23:15 | 显示全部楼层
本帖最后由 onthetrip 于 2014-11-17 23:22 编辑

续上:
request数据:
  1. POST http://222.68.172.80/data/email1/processsend.asp HTTP/1.1
  2. Host: 222.68.172.80
  3. Connection: keep-alive
  4. Content-Length: 96064
  5. Cache-Control: max-age=0
  6. Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
  7. Origin: http://222.68.172.80
  8. User-Agent: Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.63 Safari/537.36 SE 2.X MetaSr 1.0
  9. Content-Type: multipart/form-data; boundary=----WebKitFormBoundarytz4ZP8xiB2NK10ch
  10. Referer: http://222.68.172.80/data/email1/send.asp
  11. Accept-Encoding: gzip,deflate,sdch
  12. Accept-Language: zh-CN,zh;q=0.8
  13. Cookie: ASPSESSIONIDAQCRDRBR=OAJJCAJAPDBCCNPFIANGNIEM

  14. ------WebKitFormBoundarytz4ZP8xiB2NK10ch
  15. Content-Disposition: form-data; name="sjr"

  16. 小明,
  17. ------WebKitFormBoundarytz4ZP8xiB2NK10ch
  18. Content-Disposition: form-data; name="topic"


  19. ------WebKitFormBoundarytz4ZP8xiB2NK10ch
  20. Content-Disposition: form-data; name="gz"


  21. ------WebKitFormBoundarytz4ZP8xiB2NK10ch
  22. Content-Disposition: form-data; name="text"


  23. ------WebKitFormBoundarytz4ZP8xiB2NK10ch
  24. Content-Disposition: form-data; name="file1"; filename="2014年试考核.xls"
  25. Content-Type: application/vnd.ms-excel

  26. 邢唷??                >  ?                                 ?      ?
复制代码


TA的精华主题

TA的得分主题

发表于 2014-11-17 23:17 | 显示全部楼层
晕倒,每个帖子字符数限制.续上
  1. ------WebKitFormBoundarytz4ZP8xiB2NK10ch
  2. Content-Disposition: form-data; name="file2"; filename=""
  3. Content-Type: application/octet-stream


  4. ------WebKitFormBoundarytz4ZP8xiB2NK10ch
  5. Content-Disposition: form-data; name="file3"; filename=""
  6. Content-Type: application/octet-stream


  7. ------WebKitFormBoundarytz4ZP8xiB2NK10ch
  8. Content-Disposition: form-data; name="file4"; filename=""
  9. Content-Type: application/octet-stream


  10. ------WebKitFormBoundarytz4ZP8xiB2NK10ch
  11. Content-Disposition: form-data; name="file5"; filename=""
  12. Content-Type: application/octet-stream


  13. ------WebKitFormBoundarytz4ZP8xiB2NK10ch
  14. Content-Disposition: form-data; name="B1"

  15. 发送邮件
  16. ------WebKitFormBoundarytz4ZP8xiB2NK10ch
  17. Content-Disposition: form-data; name="c1"


  18. ------WebKitFormBoundarytz4ZP8xiB2NK10ch--
复制代码

TA的精华主题

TA的得分主题

发表于 2014-11-17 23:19 | 显示全部楼层
续上,我按照您的代码稍作修改,修改后的代码
  1. Sub Main()
  2.     Const SJR As String = "小明," '论坛UID
  3.     Const GZ As String = "无"
  4.     Dim Boundary As String
  5.     Dim SendData
  6.     Dim FileFullName As String
  7.     Dim FileShortName As String
  8.     Dim Title As String
  9.     Dim Filetype As String
  10.    
  11.     FileFullName = "D:\2014年试考核.xls"
  12.     FileShortName = Mid(FileFullName, InStrRev(FileFullName, "") + 1)
  13.     Title = Left(FileShortName, InStrRev(FileShortName, ".") - 1)
  14.     Filetype = "xls"
  15.    
  16.     '获取Boundary
  17.     Boundary = GetBoundary()
  18.     '获取上传所需的SendData
  19.     SendData = GetUpLoadSendData(Boundary, FileFullName, _
  20.                 "sjr", SJR, _
  21.                 "gz", GZ, _
  22.                 "file1", FileShortName, _
  23.                 "B1", "发送邮件", _
  24.                 "c1", "否")
  25.         
  26.     '上传
  27.     With CreateObject("WinHttp.WinHttpRequest.5.1")
  28.         .Open "POST", "http://222.68.172.80/data/email1/processsend.asp", False
  29.         .setRequestHeader "Content-Type", "multipart/form-data; boundary=" & Boundary
  30.         .setRequestHeader "Referer", "http://222.68.172.80/data/email1/send.asp"
  31.         .Send SendData
  32.         Debug.Print .responsetext '出现一串数字则为成功。到论坛发帖的界面可看到“未使用的附件”的提示。
  33.     End With
  34. End Sub
  35. Function GetBoundary() As String
  36.     '生成Boundary
  37.     Dim i As Integer, r As Integer
  38.     Do While i < 34
  39.         r = Int(Rnd * 75 + 48)
  40.         If r < 58 Or (r > 64 And r < 91) Or r > 96 Then
  41.             GetBoundary = GetBoundary & Chr(r)
  42.             i = i + 1
  43.         End If
  44.     Loop
  45.     GetBoundary = String(4, "-") & GetBoundary
  46. End Function

  47. Function GetUpLoadSendData(Boundary As String, FileFullName As String, ParamArray NameValue()) As Byte()
  48.     'NameValue()必须成双,前一个是名称,后一个是值
  49.     'NameValue()最后一对是文件流之后的名称值对
  50.     'NameValue()倒数第二对是文件流信息相关的两个数据
  51.    
  52.     Dim DataBefore, DataAfter
  53.     Dim arrBytData(1 To 3), bytData() As Byte
  54.     Dim i As Long, j As Long, n As Long
  55.    
  56.     '连接文件流之前的各项名称值对
  57.     For i = 0 To UBound(NameValue) - 6 Step 2 '最后三对单独处理
  58.         DataBefore = DataBefore & "--" & Boundary & vbCrLf
  59.         DataBefore = DataBefore & "Content-Disposition: form-data; name=""" & NameValue(i) & """" & vbCrLf
  60.         DataBefore = DataBefore & vbCrLf
  61.         DataBefore = DataBefore & NameValue(i + 1) & vbCrLf
  62.     Next
  63.    
  64.     '连接文件流此项的Content-Disposition
  65.     DataBefore = DataBefore & "--" & Boundary & vbCrLf
  66.     DataBefore = DataBefore & "Content-Disposition: form-data; name=""" & NameValue(i) & """; filename=""" & NameValue(i + 1) & """" & vbCrLf
  67.     DataBefore = DataBefore & "Content-Type: application/vnd.ms-excel" & vbCrLf
  68.     DataBefore = DataBefore & vbCrLf
  69.    
  70.     '文件流前面的字符串转为流
  71.     arrBytData(1) = StrToUTF8Byte(DataBefore)
  72.    
  73.     '文件转流
  74.     arrBytData(2) = FileToByte(FileFullName)
  75.    
  76.     '文件流之后的字符串(两项)
  77.     For i = UBound(NameValue) - 3 To UBound(NameValue) Step 2
  78.     DataAfter = "--" & Boundary & vbCrLf
  79.     DataAfter = DataAfter & "Content-Disposition: form-data; name=""" & NameValue(i) & """" & vbCrLf
  80.     DataAfter = DataAfter & vbCrLf
  81.     DataAfter = DataAfter & NameValue(i + 1) & vbCrLf
  82.     'DataAfter = DataAfter & "--" & Boundary ' & "--"
  83.     Next i
  84.     DataAfter = DataAfter & "--" & Boundary & "--"
  85.     arrBytData(3) = StrToUTF8Byte(DataAfter) '转为流
  86.    
  87.     '合并字符流和文件流
  88.     ReDim bytData(UBound(arrBytData(1)) + UBound(arrBytData(2)) + UBound(arrBytData(3)) + 2)
  89.     For i = 1 To 3
  90.         For j = 0 To UBound(arrBytData(i))
  91.             bytData(n) = arrBytData(i)(j)
  92.             n = n + 1
  93.         Next
  94.     Next
  95.    
  96.     GetUpLoadSendData = bytData
  97. End Function

  98. Function StrToUTF8Byte(strText)
  99.     '文本转UTF-8编码并去除BOM头
  100.     With CreateObject("adodb.stream")
  101.         .Mode = 3 'adModeReadWrite
  102.         .Type = 2 'adTypeText
  103.         .Charset = "GB2312"
  104.         .Open
  105.         .Writetext strText
  106.         .Position = 0
  107.         .Type = 1 'adTypeBinary
  108. '        .Position = 3 '去除UTF-8编码文本前面的BOM头(三个字节)
  109.         StrToUTF8Byte = .Read()
  110.         .Close
  111.     End With
  112. End Function

  113. Function FileToByte(strFileName As String)
  114.     '文件转流
  115.      With CreateObject("Adodb.Stream")
  116.         .Open
  117.         .Type = 1 'adTypeBinary
  118.         .LoadFromFile strFileName
  119.         FileToByte = .Read
  120.         .Close
  121.     End With
  122. End Function
复制代码

TA的精华主题

TA的得分主题

发表于 2014-11-17 23:21 | 显示全部楼层
本帖最后由 onthetrip 于 2014-11-17 23:26 编辑

我查看了收件箱,没有发送成功debug.print 的数据:
  1. <html>

  2. <head>
  3. <meta http-equiv="Content-Language" content="zh-cn">
  4. <meta http-equiv="Content-Type" content="text/html; charset=gb2312">
  5. <meta name="GENERATOR" content="Microsoft FrontPage 6.0">
  6. <meta name="ProgId" content="FrontPage.Editor.Document">
  7. <title>New Page 1</title>
  8. </head>

  9. <body>

  10. <p>′?ê?</p>
  11. <p>??</p>

  12. 3?ê±′í?ó!????D?μ???óê??!
复制代码
手工发送邮件成功的话,会有一个New Page 1的新窗口,提示邮件发送成功
另外:我是在点击“发送邮件”后在发邮件界面运行的代码;每次登录的Cookie都是一样的,无论清除缓存与否,设置Cookie头也没用

TA的精华主题

TA的得分主题

发表于 2014-11-18 10:47 | 显示全部楼层
wcymiss 发表于 2014-10-29 16:27
复杂登录二:58同城登录

吴老师:
58同城这个例子中,共有4个JS文件,其中两个js文件地址是通过搜索函数名getm32str,getm16str,encryptString直接在request窗口中找到。另外两个JS文件的地址(下面)是如何找到的呢?
1.https://passport.58.com/static/p ... passport_version.js
2.https://passport.58.com/static/js/5_1/jquery1.3.2.js
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

关闭

最新热点上一条 /1 下一条

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

GMT+8, 2024-12-24 01:12 , Processed in 0.037965 second(s), 11 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

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

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

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