vba抓取网页数据( 第3行字符串替换成网站的作用是创建一个IE应用程序对象)

优采云 发布时间: 2021-12-17 03:02

  vba抓取网页数据(

第3行字符串替换成网站的作用是创建一个IE应用程序对象)

  VBA IE对象的操作方法

<p> (2013-10-27 11:39:29)

   

  http://blog.sina.com.cn/s/blog_64173e0c0101bf9o.html

  <a class="SG_aBtn SG_aBtn_ico SG_turn">

转载▼</a>

标签:  vba   ie   标签   对象   图片   it 分类: 电子商务

IE和文档对象模型

  我们在实际工作中遇到网站和网页相关往往要涉及到这类问题:如何下载网页数据?网页之间的通讯是怎么实现的、它们能不能被控制等等。分析网页根据不同协变色镜可以用不同的角度去看,如数据流、标记,不过,如果你是用VB/VBA/脚本或其它支持自动化对象(AUTOMATION)的语言编程,有一个值得了解方法是掌握对象模型,将网页视为对象来自行控制,这个方法需要了解的是IE的自动化对象(InternetExplorer.Application)或IE控件(Microsoft Internet Controls),以及标准的文档对象模型(Document)<br /> 以下代码在VBA环境下进行试验——我不在意你是用WORD还是EXCEL——可以先做一行过程模块,也可以在立即窗口下逐行输入:

 </p>

  Set ieA = CreateObject("InternetExplorer.Application")  ‘创建对象

ieA.Visible = True   ‘使IE页面可见,做完这一步,在VBA之外可以看到一个新的IE

ieA.navigate "about:blank"   ‘空白页

  这几行代码的作用就是创建一个IE应用程序对象(是的,它相当于一个IE应用程序)并打开一个空白的网页。此网页独立于 VBA 应用程序(WORD 或 EXCEL)。其实必须自己关闭,或者使用ieA.Quit命令退出——注意简单关闭VBA或者SET ieA=nothing都不会退出这个页面。当然,如果你在线并且愿意,你也可以将第3行的字符串替换为网站的名称,或者替换为你主机中的一个文档名——比如C:\XXX .HTM ,或者D:\PIC\XXX.GIF,就像你在IE地址栏中输入名称浏览这些文件一样。另一种替代方法是在宿主机上直接添加一个WEB BROWS浏览器控件比如VB/VBA的表单或者工作表,也相当于上面的IE应用

  注意:WEB BROWSE 控件和单独的 IE 程序并不完全相同。比如WEB控件不能用QUIT方法退出。IE 的 NAVIGETE 方法没有复杂的 POST 参数,但同样可以引用文档对象。大多数事件和方法也是通用的

  另外,如果你访问一个已有的网页,比如因为有异步延迟的可能,如果不是立即窗口,往往保证网页是按照READYSTATE状态加载的:

  SUB LOADIE()   ‘ 在代码的常见的处理情况

Set ieA = CreateObject("InternetExplorer.Application")

ieA.Visible = True

ieA.navigate "WWW.OOXX.COM"  ‘←打开某个网页,要一定时间,但代码会往下执行

DO UNTIL ieA.Readystate=4   ‘  检查网页是否加载完毕(4表示完全加载)

   DOEVENTS                ‘ 循环中交回工作权限给系统,以免“软死机”

LOOP  

END SUB

  如果你对这个IE应用对象的相关声明和事件感兴趣,必须参考IE控件才能找到对象中的常量和事件:SHDOCVW.DLL (MICROSOFT INTERNET CONTROL)

  你可以看到,通过 ieA——创建的对象——我们可以操作它并访问它的属性。让我们继续。如果你在命令行输入并且打开的空白网页没有关闭,变量将继续有效:

  设置 doc = ieA.Document' 获取网页的文档对象

  doc.body.innerHTML = "Hello"'在文档的BODY标签中添加标记文本HELLO

  网页上有一行小字,HELLO...一般约定俗成,当然可以写其他的,HI,*敏*感*词*,EXCEL,HOME等,但这不是最重要的,我们来知道这个对象下的结构。

  由文档对象(Document)扩展而来的对象模型,它代表网页的内容,与之前的IE应用程序不是同一个系统——请注意这一点——如果我们需要使用对应的对象事件和常量编程时,VB/VBA要引用的类型库是MSHTML.TLB(MIRCOSOFT HTML OBJECT LIBRARY)

  Documnet(文档)是文档对象模型的基础,相当于OFFICE对象中的APPLICATION。拿到Document后,无论是修改网页、读写网页、触发事件,一切都好说。每个URL对应一个Documnet(这是如果确定成功导航到那个URL完成Navigate,则需要确定IE对象的READSTATE,以确保该URL对应的Document被打开)

  在Documnet下可以获得documentElement和body两个节点:

  

 

  ......              ‘前面已经取得了ieA对象,并打开空白网页,不再重复

set doc=ieA.Document

set xbody=doc.Body   ‘取得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网页

set 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

  网页上看到的mark是根节点或body下的mark节点对象(node)。每个被标记的节点对象下面,都有一个叫做ChildNodes的集合,里面收录了“节点正下方的标记”,听起来有点抽象——可以这么说,它就像一个文件目录,根目录下的一个子目录内容……

  你好

  001

  在上面的网页示例中,HTML 标记是文档的根节点,并且是文档的 Childnodes 集合的成员。从属节点的集合,就像磁盘可以有从属目录,但它本身不是目录),BODY是根节点的ChildNodes集合的成员,两个节点DIV和P是ChildNodes的两个成员BODY的集合,同样也有自己的Childnoes集合——但是我们可以直观的看到,他们的下属集合是空的。

  用程序代码提问的过程是怎样的?这种“目录式”的分层方法似乎非常有序。然后,将上面的内容保存为一个HTML文档,放到硬盘的某个目录下,写一段代码完成前面的工作。我不为你做:

  

 

  …….假定你已经用ieA为名的对象浏览了上述网页文件

set doc=ieA.Document

set xbody=doc. body   ‘取得body节点

set xI00= xbody.Childnodes.item(0)  ‘取得body的第1个节点

set xI01=xbody.Childnodes.item(0)  ‘取得bdoy的第2个节点

Msgbox xI00.innerText   ‘显示第1个节点(DIV)的文本

Msgbox xI01.outerHtml   ‘显示第2个节点(P)的完整内容

  在VB/VBA/VBS系列的语言中,item是默认方法,可以省略,不过还是写在这里加深印象。

  需要注意的是,在文档对象模型中,集合不同于OFFICE集合。首先,集合是从0开始计数的。习惯OFFICE VBA编程的朋友一​​定要注意,不同的对象架构有不同的方式。这是“0集合”。其次,它使用 Length 而不是 Count。不要习惯性地键入 Childnode.Count 来检查集合的数量。

  除了ChildNodes集合,大家在web文档对象中常见的还有一个非常流行的集合:All集合,也就是“最迷惑”的集合。各级文档和节点都有这个集合,就像名字一样。如图,没有分层,但是使用起来也很方便:

  …….

Set doc=ieA.Document

Set xCols=doc.All   ;取得文档中的所有节点集合

Set xbCols=doc.body.All ;取得body节点下所有的节点集合

  虽然任何标记节点都有ALL集合,但我们还是喜欢用DOCUMENT的ALL,原因无它,文档最大,一锅烩的ALL找起来也最合适。

ALL查找是有条件的:如果这个标记没有ID,你无法查到它的名字:

  

 

  你好

  擅长

  

 

  set tag1=doc.All.item(“myTag”).item(0)   ‘返回标记内部ID=myTag的集合并取第一个

  一开始,在我个人看来,如果网页中的 HTML 标记已经有了 ID,那么直接返回一个带有文档对象的 getElementById 的对象会更直接。这个方法不需要遍历集合:

  

 

  set tag1=doc. getElementById(“myTag”)  ‘返回第一个内部标有ID=myTag的标记

  不过,ALL集合有一个很方便的特性——至少在初学者看来是很好用的:ID可以挂到ALL集合之下:

  strX=doc.All.mytag.innerhtml     ‘呜呜呜,太好用了

  另一种方法是以标记名为集合,要用到文档对象的getElementsByName方法:

  set mydivs=doc. getElementsByName(“div”)   ‘取得所有DIV标记,注意还是集合

  今天先写到这里,下回......不定期休息

  (补一小段,特别增加,关于FORMS,某位兄弟,下面真的真的没有了,不要期望我上传实例......)

  关于文档对象的FORMS集合,因为大部分网页数据提交都是通过FORM标签提交的,所以当网页中没有FORM标签、没有ID标签或者重复ID时,可以使用FORMS集合来区分不同的FORM节点标签。:

  引用:

  设置 myForms=doc.Forms' 以获取所有 FORM 标签

  Set frmX=myForms.item(0)'第一个FORM

  FORM标签节点所代表的对象是很多朋友关心的内容——在网页对象中,它可以向服务器发送数据,让服务器刷新网页(实际上是服务器根据到一定的格式协议),我们就可以改变网页FORM作为远程函数调用接口。FORM标签中的ACTION指向的URL地址就是函数入口,FORM标签中的每一个INPUT标签节点都是该函数的参数。当 FORM.Submit 方法发出时,该函数被远程调用。是的,在服务器端,比如ASP,PHP就是老老实实的找FORM的参数,不管是用GET还是POST:

  引用:

  frmX.submit' 是的,只要Submit就相当于用户在页面上按下了FORM的send按钮

  但是它的参数,即 INPUT 标签呢?当然,你可以自己修改,访问,嗯...如果你分析一个现有的网页,想用VBA从一个空白页面(ABOUT:BLANK)“凭空”生成FORM和INPUT节点,就靠对上面的方法还不够,我们还要“创建一个节点”(createElement_x)并连接到文档的对应位置(appendChild),但这已经是另一个问题了

0 个评论

要回复文章请先登录注册


官方客服QQ群

微信人工客服

QQ人工客服


线