目录
前言:vba 爬虫相关xmlhttp的方法
1 什么是xmlhttp
1.1 定义
1.2 特点
1.3 创建xmlhttp对象的过程
1.4 XMLHTTP对象创建的几种方法:
2 XMLHTTP方法:
2.1 xmlhttp.open(Method, Url, Async, User,Password)
2.1.1 xmlhttp.open()方法
2.1.2 参数
2.1.3 xmlhttp.open(get, url)
2.1.4 xmlhttp.open(post, url)
2.1.5 xmlhttp.open(put )
2.1.6 xmlhttp.open(propfind )
2.2 XmlHttp.send(varBody)
2.3 setRequestHeader(bstrHeader, bstrValue)
2.4 abort
2.5 getAllResponseHeaders
2.6 getResponseHeader("header")
2.7 这个? XMLHttpRequest.open()
2.8 XMLHttpRequest.send(varBody)
2.9 response.write(objXML.responseText)
3 XMLHTTP属性:
3.1 xmlhttp的属性罗列
3.1 xml.http.readyState
3.2 onreadystatechange
3.3 xml.http.status
3.4 xml.http.statusText
3.5 responseBody:
3.6 XmlHttp.responsetext 即是网页内容
3.7 responseStream:
3.8 responseXML:
前言:vba 爬虫相关xmlhttp的方法
- 除了EXCEL里直接用 来自网站可以爬数据
- VBA也可以写爬虫代码
- 但是设计 xmlhttp 相关的内容
1 什么是xmlhttp
1.1 定义
- XMLHTTP是个传送XML格式数据的超文本传输协议。
- XMLHTTP的数据传输过程更为灵活一些:
- 下面是网上说灵活的地方
- XMLHttpRequest可以提供不重新加载页面的情况下更新网页,在页面加载后在客户端向服务器请求数据,在页面加载后在服务器端接受数据,在后台向客户端发送数据
- 它上传的指令可以是XML格式数据,也可以是字符串,流,或者一个无符号整数数组。还可以是URL的参数。
- 它下达的结果可以是XML格式数据,也可以是字符串,流,或者一个无符号整数数组。
1.2 特点
- 也是跨语言的
- 现在所知的,vb,js
1.3 创建xmlhttp对象的过程
客户端调用XMLHTTP的过程很简单,只有5个步骤:
- 创建XMLHTTP对象
- 打开与服务端的连接,同时定义指令发送方式,服务网页(URL)和请求权限等。
- 客户端通过Open命令打开与服务端的服务网页的连接。与普通HTTP指令传送一样,可以用"GET"方法或"POST"方法指向服务端的服务网页。
- 发送指令。
- 等待并接收服务端返回的处理结果。
- 释放XMLHTTP对象
创建xmlhtml对象过程的例子:见下面代码
Sub t1()
strUrl = "http://www.86pm25.com/paiming.htm"
getHtmlStr (strUrl)
End Sub
Public Function getHtmlStr(strUrl)
Dim XmlHttp
Set XmlHttp = CreateObject("Microsoft.XMLHTTP")
XmlHttp.Open "GET", strUrl, True
XmlHttp.send
Content = XmlHttp.responsetext
ThisWorkbook.Sheets("sheet5").Cells(1, 1) = Content
' getHtmlStr = StrConv(XmlHttp.ResponseBody, vbUnicode)
' Set XmlHttp = Nothing
End Function
1.4 XMLHTTP对象创建的几种方法:
(vbs)
- Msxml2.XMLHTTP是高版本,受msxml3.dll+支持
- Microsoft.XMLHTTP是低本,一般是msxml2.6以下版本使用
- MSXML2.XMLHTTP.6.0 据说是更高的版本
什么证书,目标地址是https的么?如果这样,安装msxml4以上版本的xml解析器,然后
set http = server.createobject("msxml2.serverxmlhttp")
http.setoption 2, 13056'意思是忽略所有ssl错误
忘记带版本号了,msxml2.serverxmlhttp.4.0
Set http=Server.CreateObject("Msxml2.ServerXMLHTTP.3.0")
http.setOption(2) = 13056
Set objXmlHttp= Server.CreateObject("WinHttp.WinHttpRequest.5.1")
objXmlHttp.option(9) = 2720
- dim objxml as object
- Set objXML = CreateObject("Msxml2.XMLHTTP")
- Set objXML = CreateObject("MSXML2.XMLHTTP.6.0")
- Set objXML = CreateObject("Microsoft.XMLHTTP")
(javascript)
- var xml = new ActiveXObject("Microsoft.XMLHTTP")
- Set xml = Server.CreateObject("MSXML2.ServerXMLHTTP")
2 XMLHTTP方法:
- 百度百科上就有,学习一遍
Microsoft.XMLHTTP_百度百科含义Microsoft.XMLHttp组件的属性方法https://baike.baidu.com/item/Microsoft.XMLHTTP/5265442?fr=aladdin
2.1 xmlhttp.open(Method, Url, Async, User,Password)
2.1.1 xmlhttp.open()方法
- open 创建一个新的http请求,并指定此请求的方法、URL以及验证信息(用户名/密码) 去打开指定网址
- 语法
- xmlhttp.open(Method, Url, Async, User,Password)
- open(bstrMethod, bstrUrl, varAsync, bstrUser, bstrPassword)
- 调用open方法后,会将readyState修改为1。
2.1.2 参数
bstrMethod
- 例如:POST、GET、PUT及PROPFIND。
- 大小写不敏感
- xmlhttp.post 用"POST"方式发送数据,可以大到4MB,
- xmlhttp.GET 只能256KB
- xmlhttp.PUT
- xmlhttp.PROPFIND
bstrUrl
- 请求的URL地址
- 可以为绝对地址也可以为相对地址。
varAsync[可选]
- varAsync: 是否同步执行。
- 布尔型,
- 指定此请求是否为异步方式
- 默认/ 缺省为True,即异步执行,
- 如果写 False,同步执行,只能在DOM中实施同步执行。
bstrUser[可选]
- 如果服务器需要验证,此处指定用户名
- 如果未指定,当服务器需要验证时,会弹出验证窗口。
bstrPassword[可选]
- 验证信息中的密码部分,
- 如果用户名为空,则此值将被忽略。
2.1.3 xmlhttp.open(get, url)
- open()
- 打开网页,取得信息
Dim XmlHttp
Set XmlHttp = CreateObject("Microsoft.XMLHTTP")
XmlHttp.Open "GET", strUrl, True
XmlHttp.send
2.1.4 xmlhttp.open(post, url)
- 如果Open方法定义为POST,可以定义表单方式上传
- 还可以发送用户名,密码!
- 上传信息是这样
- XMLHTTP.setRequestHeader
- XMLHTTP.send
Set XMLHTTP = CreateObject("Microsoft.XMLHTTP")
XMLHTTP.Open "POST", StrUrl, True
XMLHTTP.setRequestHeader "Content-Length", Len(PostData)
XMLHTTP.setRequestHeader "CONTENT-TYPE", "application/x-www-form-urlencoded"
XMLHTTP.send (StrData)
set oxh=createobject("Microsoft.XMLHTTP")
postdata="username=abc&password=123"
oxh.Open "post",url,false
oxh.setRequestHeader "Content-Length",len(postdata)
oxh.setRequestHeader "CONTENT-TYPE", "application/x-www-form-urlencoded"
oxh.send postdata 'send用户名密码
2.1.5 xmlhttp.open(put )
- PUT创建或替换资源。因此,Content-Type头字段应该包含您要发送的表示的内容类型
var string = encodeURIComponent("Text String!")
var req = new XMLHttpRequest()
req.open("PUT", "example/data.txt", false)
req.setRequestHeader("Content-type", "application/x-www-form-urlencoded")
req.setRequestHeader("Content-length", string.length)
req.setRequestHeader("Connection", "close")
req.send(string)
2.1.6 xmlhttp.open(propfind )
很少见
2.2 XmlHttp.send(varBody)
- varBody:指令集。
- 可以是XML格式数据,也可以是字符串,流,或者一个无符号整数数组。
- 也可以省略,让指令通过Open方法的URL参数代入。
- 发送数据的方式分为同步和异步两种。
- 在异步方式下,数据包一旦发送完毕,就结束Send进程,客户机执行其他的操作;
- 而在同步方式下,客户机要等到服务器返回确认消息后才结束Send进程。
2.3 setRequestHeader(bstrHeader, bstrValue)
- bstrHeader:HTTP 头(header)
- bstrValue:HTTP 头(header)的值
可以配合 open(post ) 使用
如果Open方法定义为POST,可以定义表单方式上传:
xmlhttp.setRequestHeader "Content-Type", "application/x-www-form-urlencoded"
2.4 abort
- 取消/停止 当前 HTTP 请求
- 如果XMlHttp对象被用过后readyState状态一直是4,所以就不在触发OnReadyStateChange事件了,因此responseText只能显示一次,以后就无法工作了,
- 需要在后面加上 XMlHttp对象.abort一切搞定
2.5 getAllResponseHeaders
- 从响应信息中检索所有的标头字段
2.6 getResponseHeader("header")
2.7 这个? XMLHttpRequest.open()
- XMLHttpRequest.open(bstrMethod, bstrUrl, varAsync, bstrUser, bstrPassword);
- 不同于xmlhttp.open()方法
2.8 XMLHttpRequest.send(varBody)
send 发送请求到http服务器并接收回应
XMLHttpRequest.send(varBody);
参数
varBody 欲通过此请求发送的数据。
调用send方法后,会先调用onreadystatechange方法,此时readyState状态为1,然后会已经进程将readyState修改为2、3、4
一般情况下,使用Ajax提交或者获取参数可以采用GET、POST方式,使用GET方法将要提交的参数写到open方法的url参数中,此时send方法的参数为null。
例如 :
var url = "login.jsp?user=XXX&pwd=XXX";
xmlHttpRequest.open("GET",url,true);
xmlHttpRequset.send();
此外,也可以使用send方法传递参数。使用send方法传递参数使用的是POST方法,需要设定Content-Type头信息,模拟HTTP POST方法发送一个表单,这样服务器才会知道如何处理上传的内容。参数的提交格式和GET方法中url的写法一样。设置头信息前必须先调用open方法。
例如:
xmlHttpRequest.open("POST","login.jsp",true);
xmlHttpRequest.setRequestHeader("Content-Type","application/x-www-form-urlencoded;charset=UTF-8");
xmlHttpRequest.send("user="+username+"&pwd="+password);
需要注意的是根据提交方式的不同,两种提交方式分别调用后台的doGet方法和doPost方法。
2.9 response.write(objXML.responseText)
3 XMLHTTP属性:
- 搜到的属性如下
Microsoft.XMLHTTP_百度百科含义Microsoft.XMLHttp组件的属性方法https://baike.baidu.com/item/Microsoft.XMLHTTP/5265442?fr=aladdin
3.1 xmlhttp的属性罗列
返回状态
- status: Long型 服务器返回的HTTP状态码
- statusText : String型 服务器HTTP响应行状态
状态码等
- xml.http.readyState
- onreadystatechange:在同步执行方式下获得返回结果的事件句柄。只能在DOM中调用。
返回内容
- 除了 responseText 结果返回为字符串。其他不能直接打出来吧,其他格式取出!
- 分别用什么方法取出呢?
- responseBody: 结果返回为无符号整数数组。
- responseStream: 结果返回为IStream流。
- responseText : 结果返回为字符串。
- responseXML: 结果返回为XML格式数据。
3.1 xml.http.readyState
- XMLHTTP对象中的readyState属性能够反映出服务器在处理请求时的进展状况。
- 客户机的程序可以根据这个状态信息设置相应的事件处理方法。
- status长整形,此属性只读,返回当前请求的http状态码,此属性仅当数据发送并接收完毕后才可获取。
- readyState用来记录当前请求的状态,只读。
- 0(未初始化) Response对象已创建,但是尚未初始化,XML文档上载过程尚未结束(尚未调用open方法)
- 1(初始化) XML文档已经装载完毕, 对象已初始化(调用了open方法,尚未调用send方法 )
- 2(发送数据) XML文档已经装载完毕,正在处理中. (send方法已调用,但是当前的状态及http头未知)
- 3(数据传送中) 部分XML文档已经解析, 已接收部分数据,因为响应及http头不全,这时通过responseBody和responseText获取部分数据会出现错误
- 4(完成) 文档已经解析完毕,数据接收完毕,客户端可以接受返回消息,此时可以通过通过responseBody和responseText获取完整的回应数据
Set xmlobject = CreateObject("Microsoft.XMLHTTP")
xmlobject.Open "GET", strURL, False
xmlobject.Send
If xmlobject.readyState = 4 Then
strHTML = xmlobject.Responsetext
End If
3.2 onreadystatechange
- 当readyState发生改变时,调用onreadystatechange方法,onreadystatechange需要自己定义。
- 在同步执行方式下获得返回结果的事件句柄。只能在DOM中调用。
3.3 xml.http.status
3.4 xml.http.statusText
3.5 responseBody:
- ResponseBody是二进制的数据,是服务器传来的没有经过任何加工的数据。
3.6 XmlHttp.responsetext 即是网页内容
responseText 将响应信息作为字符串返回.只读
2 ResponseText是按照utf-8编码把ResponseBody转换而成,也就是:ResponseText=ByteToStr(ResponseBody,"UTF-8")
Sub t1()
strUrl = "http://www.86pm25.com/paiming.htm"
getHtmlStr (strUrl)
End Sub
Public Function getHtmlStr(strUrl)
Dim XmlHttp
Set XmlHttp = CreateObject("Microsoft.XMLHTTP")
XmlHttp.Open "GET", strUrl, True
XmlHttp.send
r1 = XmlHttp.responsetext
' r2 = XmlHttp.responsexml
' r3 = XmlHttp.responsebody
' r4 = XmlHttp.responsestream
ThisWorkbook.Sheets("sheet5").Cells(1, 1) = r1
' ThisWorkbook.Sheets("sheet5").Cells(1, 2) = r2
' ThisWorkbook.Sheets("sheet5").Cells(1, 3) = r3
' ThisWorkbook.Sheets("sheet5").Cells(1, 4) = r4
' getHtmlStr = StrConv(XmlHttp.ResponseBody, vbUnicode)
' Set XmlHttp = Nothing
End Function
'''Function getHtmlStr(strUrl)
''' Dim XmlHttp
''' Set XmlHttp = CreateObject("Microsoft.XMLHTTP")
''' XmlHttp.Open "GET", strUrl, True
'''
'''' If XmlHttpRequest.status_code = 200 Then
'''
''' XmlHttp.send
'''
''' ' Content = XmlHttp.responsetext
''' ' arr1 = Split(Content, "<Holding>") 'You cannot dim arr1() at the beginning
''' ' arr2 = Split(arr1(1), "</Holding>")
''' ' Sheet3.Cells(i, 5) = arr2(0)
'''
'''
'''
''' ThisWorkbook.Sheets("sheet5").Cells(1, 1) = Content
''' getHtmlStr = StrConv(XmlHttp.ResponseBody, vbUnicode)
''' Set XmlHttp = Nothing
'''
'''' End If
'''End Function
必须绕一手?
r1 = XmlHttp.responsetext
ThisWorkbook.Sheets("sheet5").Cells(1, 1) = r1
这样就不行?
ThisWorkbook.Sheets("sheet5").Cells(1, 1) =XmlHttp.responsetext
3.7 responseStream:
● responseStream:结果返回为IStream流 对象。
3.8 responseXML:
- responseXML 将响应信息格式化为Xml Document对象并返回,只读
超时问题如何
下面的xml文件是动态生成的最后用xmlHTTP传送出去,这是一个在客户端JavaScript脚本里的内容,当然你也可以写在服务器,但是要相应的改一些东西:(仅供大家参考,了解它的用法)
var xmlDoc=new ActiveXObject("MSXML2.DOMDocument");
flag=xmlDoc.loadXML("");
newNode =xmlDoc.createElement("编码")
MarkNode=xmlDoc.documentElement.appendChild(newNode);
newNode =xmlDoc.createElement("StartMark")
newNode.text=StartMark;
MarkNode.appendChild(newNode)
newNode =xmlDoc.createElement("EndMark")
newNode.text=EndMark;
MarkNode.appendChild(newNode)
newNode =xmlDoc.createElement("日期")
DateNode=xmlDoc.documentElement.appendChild(newNode);
newNode =xmlDoc.createElement("StartDate");
newNode.text=StartDate;
DateNode.appendChild(newNode)
newNode =xmlDoc.createElement("EndDate")
newNode.text=EndDate;
DateNode.appendChild(newNode);
newNode =xmlDoc.createElement("数量")
SLNode =xmlDoc.documentElement.appendChild(newNode);
newNode =xmlDoc.createElement("StartSL")
newNode.text=StartShuL
SLNode.appendChild(newNode)
newNode =xmlDoc.createElement("EndSL");
newNode.text=EndShuL
SLNode.appendChild(newNode);
newNode =xmlDoc.createElement("单价")
DJNode =xmlDoc.documentElement.appendChild(newNode)
newNode =xmlDoc.createElement("StartDJ")
newNode.text=StartDanJ;
DJNode.appendChild(newNode);
newNode =xmlDoc.createElement("EndDJ")
newNode.text=EndDanJ;
DJNode.appendChild(newNode);
newNode =xmlDoc.createElement("金额")
JENode =xmlDoc.documentElement.appendChild(newNode)
newNode =xmlDoc.createElement("StartJE")
newNode.text=StartJinE
JENode.appendChild(newNode)
newNode =xmlDoc.createElement("EndJE")
newNode.text=EndJinE
JENode.appendChild(newNode)
newNode =xmlDoc.createElement("仓库代码")
newNode.text=CK;
xmlDoc.documentElement.appendChild(newNode)
newNode =xmlDoc.createElement("票号")
newNode.text=RKPH;
xmlDoc.documentElement.appendChild(newNode)
newNode =xmlDoc.createElement("单位代码")
newNode.text=CorpName;
xmlDoc.documentElement.appendChild(newNode)
newNode =xmlDoc.createElement("BiaoShi")
newNode.text=Biaoshi
xmlDoc.documentElement.appendChild(newNode)
newNode =xmlDoc.createElement("FindCate")
newNode.text=FindCate
xmlDoc.documentElement.appendChild(newNode)
var xh =new ActiveXObject("MSXML2.XMLHTTP")
xh.open("POST","Find.asp",false)
xh.setRequestHeader("Content-Type","text/xml")
xh.setRequestHeader("Content-Type","gb2312")
xh.send(xmlDoc);
我的每一个newNode的text值是一个变量,也就是我客户端form 中input的值
-------------------------------------------------------------------
ASP小偷程序如何利用XMLHTTP实现表单的提交
利用XMLHTTP来制作小偷的具体细节落伍很多人都发过和讨论过了,但是在制作ASP小偷的过程中,很多人就发现ASP小偷不如PHP小偷的那么强
大了。确实,如果在原网站如果存在表单提交或cookies的验证,对于ASP来说,不使用基于SOCKET的组件就难以完成,其实,XMLHTTP的另外两
个方法被我们忽略了,而这正是问题的关键。
下面首先来说说这个方法
1。.send()
由于流行的小偷是使用的GET而不是POST来传送数据,所以很多人忽略了这个方法,而使用SEND发送数据也很简单,就是SEND("内容"),可是,
发送表单就不是这么简单,因为你发送的表单如果是中文的话,就要牵扯到编码的问题了。
首先,你在OPEN 时要确定是用POST 即 .open("POST",地址,是否异步)
然后,在SEND里面加上你表单的内容,比如说,你要提交的表单有3个表单域,分别是A,B,C,对应的值分别是1,2,3,那么,你在SEND里这
样写就可以提交表单了,.send("A=1&B=2&C=3"),怎么样,很简单吧,是不是没想到呢?但是别高兴的太早了,我前面说到了,如果表单的值是
中文的话,数据传输的就会出错了。这里我们借助一个函数escape(),熟悉JAVASCRIPT的朋友都应该知道这个函数的作用了,现在VBSCRIPT同样支持这个函数。.send("A=escape('值1')&B=escape('值2')&C=escape('值3')")
2。.setRequestHeader()
接着上面的所说,你的数据send出去了,对方却不会接收到,为什么了,其实,那是因为你的HTTP头少了一个东西,然后用这个函数把加上去就可以了,具体就是.setRequestHeader("CONTENT-TYPE","application/x-www-form-urlencoded"), 告诉对方你是提交了一个urlencode编码的表单。
好的,说完了表单的提交来说怎么传送cookies和session
其实传送cookies也很简单了,同样利用这个函数在HTTP头里添加东西,比如,我当前在落伍的cookies是
cdb_sid=ybBiK0; cdb_cookietime=315360000; cdb_oldtopics=D869008D; cdb_visitedfid=1D45; cdb_auth=AQYHXVFDGERdsggVQA1VYUgxQDwFVV1dUAlwFAFRXVwU%2FbAIJB1lUCg; cdb_fid45=1113370145
现在我要发送这个cookies就直接是.setRequestHeader("Cookie","cdb_sid=ybBiK0; cdb_cookietime=315360000; cdb_oldtopics=D869008D; cdb_visitedfid=1D45; cdb_auth=AQYHXVFDGERdsggVQA1VYUgxQDwFVV1dUAlwFAFRXVwU%2FbAIJB1lUCg; cdb_fid45=1113370145")
当然,有些网站页面有页面判断功能,这个也不难,就是.setRequestHeader("Referer","来路的绝对地址")
这里还有个重要问题,就是这个方法由于是写HTTP头的,所以不能更改现有的HTTP头,对于怎么用asp获取对方页面的cookies或session并且发出去.