vba抓取网页数据(网页根据不同协变色镜的角度去看网页和网页相关 )
优采云 发布时间: 2022-02-02 16:11vba抓取网页数据(网页根据不同协变色镜的角度去看网页和网页相关
)
当我们在实际工作中遇到网站网页时,经常要处理这样的问题:如何下载网页数据?网页之间的通信是如何实现的,是否可以控制等等。分析网页可以根据不同的同色镜从不同的角度查看,比如数据流,标记,但是如果你是用VB/VBA/脚本或者其他支持自动化对象(AUTOMATION)的语言编程,还是值得了解的方法是掌握对象模型,把网页当作对象进行自我控制。这个方法需要知道的是IE的自动化对象(InternetExplorer.Application)或者IE控件(Microsoft Internet Controls),以及标准的文档对象模型(Document)
Set ieA = CreateObject("InternetExplorer.Application") '创建对象
ieA.Visible = True '使IE页面可见,经过这一步,可以在VBA之外看到一个新的IE
ieA.navigate "about:blank" '空白页
这些代码行的作用是创建一个 IE 应用程序对象并打开一个空白网页。这个网页是独立于VBA应用程序(WORD或EXCEL)的,其实你得自己关闭,还是用ieA.Quit命令退出??请注意,简单地关闭 VBA 或 SET ieA=nothing 不会退出此页面。当然,如果您正在上网并想上网,您也可以将第 3 行的字符串替换为 网站 名称,或者使用您主机上的文件名?例如,C:XXX。HTM 或 D:PICXXX.GIF,当您通过在 IE 地址栏中键入名称来浏览这些文档时。另一种可选方法是直接在宿主机上添加一个WEB BROWS浏览器控件如VB/VBA的表单或工作表,也相当于上面的IE应用
注意:WEB BROWSE 控件和个别 IE 程序并不完全相同。例如,不能使用 QUIT 方法退出 WEB 控件。IE 的 NAVIGETE 方法没有复杂的 POST 参数,但是可以用同样的方式引用文档对象。大多数事件和方法也很常见
另外,如果你访问一个已有的网页,例如,因为可能有异步延迟,如果不是即时窗口,通常会保证网页是按照READYSTATE的状态加载的:
SUB LOADIE() ' 代码中的常见处理案例
设置 ieA = CreateObject("InternetExplorer.Application")
ieA.Visible = True
ieA.navigate "" '←打开一个网页,需要一定的时间,但是代码会执行下来
DO UNTIL ieA.Readystate=4 ' 检查页面是否加载(4 表示完全加载)
DOEVENTS 将工作权移交给循环中的系统以避免“软崩溃”
环形
结束子
如果对这个IE应用对象的相关声明和事件感兴趣,一定要参考IE控件找到对象中的常量和事件:SHDOCVW.DLL(MICROSOFT INTERNET CONTROL)
你能看到的是通过ieA??对象创建了吗??我们可以操纵它,也可以访问它的属性。下面继续。如果你在命令行输入,你打开的空白网页并没有关闭,变量将继续有效:
Set doc = ieA.Document '获取网页的文档对象
doc.body.innerHTML = "Hello" '将标记文本 HELLO 添加到文档的 BODY 标签
网页上写了一行小字,HELLO……一个通用的约定,我们需要知道这个对象下的结构。
从文档对象(Document)扩展而来的对象模型,代表网页的内容,和之前的IE应用不是同一个系统吗??请注意这个??如果我们在编程的时候使用对应的对象事件和常量,VB/VBA中要引用的类型库就是MSHTML.TLB(MIRCOSOFT HTML OBJECT LIBRARY)
Documnet(文档)是文档对象模型的基础,相当于OFFICE对象中的APPLICATION。获取到Document之后,无论是修改网页,读取还是写入网页,还是触发事件,一切都好说,每个URL对应一个Documnet(这就是如果确定导航成功的话Navigate到那个URL,需要先判断IE对象READSTATE,才能判断打开该URL对应的Document)
在Documnet下可以获得两个节点documentElement和body:
... '之前已经获取了ieA对象,打开一个空白网页,不再重复
设置 doc=ieA.Document
set xbody=doc.Body '获取正文对象
set xDoc=doc.documentElement '获取根节点
前面说过,body相当于被标记的对象,根节点相当于网页中被标记的元素对象。在 MHTML 类型库定义中,它们都属于 HTMLHtmlElement 类型的对象。我将这种类型的对象称为“节点”,但请注意,文档对象不是节点对象,它是 HTMLDocument 类型。根节点和正文节点的区别在于,根节点包括整个网页。在 HTML 文档对象模型中,这种类型的对象有几个属性来获取内容:
object.innerHtml '对象内的 HTML 文本
Object.OuterHtml '对象中的 HTML 文本,包括对象本身的 HTML 标记
Object.innerText '对象内部的TEXT,不包括HTML标签
Object.OuterText '同上,包括对象本身的文本
所以,如果我们想抓取某个网站的所有HTML内容,代码可以这样写:
... '之前已经获取到ieA对象,打开一个URL页面
设置 doc=ieA.Document
set xDoc=doc.documentElement '获取根节点
strX=xDoc.OuterHtml '获取所有HTML内容
这种取值方式也可以作为EXCEL中的单元格值:
set shDocX=APPLICATION.ACTIVEWORK.ACTIVESHEET '从应用程序、工作簿到当前工作表,这是EXCEL的工作簿对象模型
set rngX=shDocX.Rang("a1") '获取单元格(其实不一定是网格,只要是RANGE类型的对象即可)
X=rngX.VALUE '获取VALUE值,也可以读取只读TEXT
您在网页上看到的标记是根节点或正文下的标记节点对象(节点)。每个标签节点对象下,都有一个名为ChildNodes的集合,里面收录了“该节点正下方的标签”,听起来有点抽象??比方说它就像一个文件目录,根目录下的子目录内容……
你好
001
在上面的网页示例中,HTML 标记是文档的根节点,是 Document 的 Childnodes 集合的成员(再次需要注意的是,Document 不是节点,而是另一种类型的对象:父文档,但它可以有下级节点集合,就像磁盘可以有下级目录,但它本身不是目录),BODY是根节点的ChildNodes集合的成员,DIV和P节点是BODY的ChildNodes集合是集合的两个成员,同样它也有自己的Childnoes集合??但是我们可以直观的看到他们的下属集合是空的。
请问使用程序代码的过程是怎样的?这个“目录”层次结构看起来非常有序。然后,将上面的内容保存为HTML文档,放到硬盘的某个目录下,写一段代码就完成了前面的工作。我不为你做:
…….假设你浏览了上面的网页文件,对象名为 ieA
设置 doc=ieA.Document
set xbody=doc.body '获取正文节点
set xI00= xbody.Childnodes.item(0) '获取body的第一个节点
set xI01=xbody.Childnodes.item(0) '获取bdoy的第二个节点
Msgbox xI00.innerText '显示第一个节点(DIV)的文本
Msgbox xI01.outerHtml '显示第二个节点的完整内容(P)
在VB/VBA/VBS系列语言中,item是默认方法,可以省略,但还是写在这里加深印象。
需要注意的是,在文档对象模型中,集合不同于OFFICE集合。首先,集合是从0开始计数的。习惯OFFICE VBA编程的朋友一定要注意,不同的对象架构有不同的方法。此处使用“0 集合”。其次,它使用的计数属性是 Length 而不是 Count。不要习惯性地键入 Childnode.Count 来检查集合的数量。
除了 ChildNodes 集合之外,Web 文档对象中最常见的集合是 All 集合,这是“最令人困惑”的集合。各级文档和节点都有这个集合,就像名字一样。如图所示,它是非分层的,但使用起来也很方便:
……。
设置doc=ieA.Document
Set xCols=doc.All ;获取文档中的所有节点集
Set xbCols=doc.body.All ;获取body节点下的所有节点集
尽管任何标记的节点都有一个 ALL 集合,但我们仍然喜欢使用 DOCUMENT 的 ALL,没有其他原因。文档最大,一锅ALL最适合找。
所有查找都是有条件的:如果标签没有 ID,则无法查找其名称:
你好
擅长
set tag1=doc.All.item(“myTag”).item(0) '返回标签内部ID=myTag的集合,取第一个
最初,在我个人看来,如果网页中的 HTML 标签已经有了 ID,那么直接使用 document 对象的 getElementById 来返回一个对象会更直接。这种方法不需要经过集合:
set tag1=doc.getElementById("myTag") '返回第一个 ID=myTag 的标签
但是,ALL集合有一个非常方便的功能??至少对于初学者来说非常有用:ID 可以附加到 ALL 集合中:
strX=doc.All.mytag.innerhtml 'Woooooooooooooooooooooooooooooooooooo 非常有用
另一种方法是使用文档对象的 getElementsByName 方法标记命名集合:
set mydivs=doc.getElementsByName("div") '获取所有DIV标签,注意采集
关于文档对象的FORMS集合,由于网页的大部分数据提交都是通过FORM标签提交的,所以当网页中没有FORM标签、没有ID标签或ID标签时,可以使用FORMS集合来区分不同的FORM节点。重复。:
引用:
Set myForms=doc.Forms '获取所有FORM标签
设置 frmX=myForms.item(0) '第一个 FORM
FORM标签节点所代表的对象是很多朋友关心的内容??在网页对象中,可以向服务器发送数据,让服务器刷新网页(其实就是服务器按照一定的格式协议发回数据),我们就可以向网页发送数据了。FORM被视为远程函数调用接口。FORM标签中ACTION指向的URL地址就是函数入口,FORM标签中的每个INPUT标签节点都是函数的参数。发出 FORM.Submit 方法时,将远程调用该函数。现在,在服务器端,比如ASP,PHP就是老老实实的找FORM的参数,不管你用GET还是POST:
引用:
frmX.submit '可以,只要Submit就相当于用户在页面按下FORM的发送按钮
跟着我!