日期:2014-05-17  浏览次数:20888 次

ASP小偷(三):文档对象模型DOM

ASP小偷(三):文档对象模型DOM
2009年08月22日
  
  获取到网页的源码之后,接下来的事情就是从源码中提取自己所需的数据。最简单易懂的方法就是使用字符串处理语句进行处理,主要用到Instr,Replace,Left,Right,Mid等函数。正则表达式也是一种快捷有效的方法。
    另外也有一些使用控件对象处理的方法,主要有以下几种:
    1.  XMLHTTP对象,速度不错,受网页源代码改变影响,但是处理网页源文件最方便自由。
    2. InternetExplorer对象,速度一般,受网页源代码改变影响,还需要激活IE,不喜欢。
    3. Execll中的QueryTables对象,平均速度最快,而且基本不受网页源代码改变影响,就是想获取多页数据的时候麻烦,而且多了一个web查询区域需要删除。对于纯数据表格网页是理想的处理方法,但对于提取现实的复杂网页中我们所需的数据时则比较难处理,想当于提取了innerText并且分离到单元格中。使用方法如下:
  Dim qt As QueryTable
  connstring="url;http://www.mysite.com"  With ActiveSheet.QueryTables.Add(Connection:=connstring, Destination:=Range("B1"))
  .Refresh
  End With
    4. WebBrowser对象,第一次速度次于XMLHTTP,之后就很快,受网页源代码改变影响,原理同InternetExplorer。
    现就IE对象和文档对象模型(DOM)的应用作具体说明。
    分析网页根据不同情况可以用不同的角度去看,有一个值得了解的方法是掌握对象模型,将网页视为对象来自行控制,这个方法需要了解的是IE的自动化对象(InternetExplorer.Application)或WebBrowser对象(Microsoft Internet Controls),以及标准的文档对象模型(Document),以下代码在VBA环境下进行试验――我不在意你是用WORD还是EXCEL――可以先做一行过程模块,也可以在立即窗口下逐行输入:
   Set ieA = CreateObject("InternetExplorer.Application")  ‘创建IE对象 ieA.Visible = True   ‘使IE页面可见,做完这一步,可以看到一个新的IE ieA.navigate "about:blank"   ‘打开一个空白的网页。
    这个网页独立于VBA的应用程序(WORD或EXCEL)之外,事实上,你必须自已关掉它,或者用ieA.Quit下令退出――注意一下,单纯的关闭VBA或SET ieA=nothing是不会退出这个网页的。当然,如果你正在上网并且愿意,在第3行也可以将第3行的字符串替换成一个网站的名字,或者替换成一个你主机中的文档名――比如C:\XXX.HTM,或D:\PIC\XXX.GIF,正如你在IE地址栏输入名称浏览这些文档一样。另一种可选择的方法是直接在VB/VBA的窗体或工作表等宿主上增加一个的WEB BROWS 浏览器控件,也相当于上面的IE应用程序注:WEB BROWSE控件和单独的IE程序并不是完全相同的,例如WEB控件不能用QUIT方法退出,IE的NAVIGETE方法没有复杂的POST参数,但文档对象都可以用同样的方法引用,大部分事件和方法也通用另外,如果访问一个已经存在的网页,例如http://www.myweb.com,因为可能产生异步的延时,所以如果不是立即窗口,往往根据READYSTATE的状态保证网页加载完毕:
  SUB LOADIE()   ‘ 在代码的常见的处理情况    Set ieA = CreateObject("InternetExplorer.Application")    ieA.Visible = True    ieA.navigate "http://www.myweb.com"  '打开某个网页,要一定时间,但代码会往下执行    DO UNTIL ieA.Readystate=4   '检查网页是否加载完毕(4表示完全加载)     DOEVENTS                '循环中交回工作权限给系统,以免“软死机”,vbs中用wscript.sleep 500代替    LOOP    END SUB
    如果对这个IE应用程序对象的相关声明和事件感兴趣,就要引用IE控件找到对象中的常量和事件:SHDOCVW.DLL(MICROSOFT INTERNET CONTROL)。你可以看到的是,通过创建的对象,我们可以操作它,也可以访问它的属性。下面继续,如果前面你是在命令行输入,打开的那个空白网页没有关闭,变量是继续有效的:
  Set doc = ieA.Document     ‘取得网页的文档对象  doc.body.innerHTML = "Hello"   ‘在文档的BODY标记内加上标记文字HELLO
    从文档对象(Document)以下展开的对象模型,它代表网页的内容,和前面那个IE的应用程序不是同一个体系――请注意这一点――如果我们编程时要用到对应的对象事件和常量,在VB/VBA中要引用的类型库是MSHTML.TLB(MIRCOSOFT HTML OBJECT LIBRARY)
    Documnet(文档)是文档对象模型的基础,相当于OFFICE对象中的APPLICATION,取得Document之后,不论修改网页还是读写网页,还是触发事件,一切都好说,在网页完全加载的前提下,每个URL都对应有一个Documnet。
    在Documnet之下可以取得documentElement和body两个节点:
   ......              ‘前面已经取得了ieA对象,并打开空白网页,不再重复 set doc=ieA.Document set xbody=doc.Body   ‘取得body对象 set xDoc=doc. documentElement  ‘取得根节点
    body对象相当于标记的对象,根节点documentElement相当于网页中的标记元素的对象,MHTML的类型库定义里,它们都属于HTMLHtmlElement类型的对象,下面我把这种类型的对象称为一个“节点”,不过要注意的是文档对象不是节点对象,它是HTMLDocument类型。根节点和body节点不同的是根节点包括整个网页,在HTML的文档对象模型中,这类对象有几种属性可以取得其中的内容:
   对象.innerHtml   ‘对象内部的HTML文本
   对象.OuterHtml   ‘对象中的HTML文本,包括对象本身的HTML标记在内
   对象.innerText    ‘对象内部的TEXT,不包括HTML标记
   对象.OuterText    ‘同上,包括对象本身的文本
  所以,如果我们要抓取某个网站的所有HTML内容,代码可以这样写:
  ......              ‘前面已经取得了ieA对象,并打开某URL网页  set doc=ieA.Document  set xDoc=doc. documentElement  ‘取得根节点  strX=xDoc.OuterHtml    ‘取得所有的HTML内容
    在网页上看到的标记,就是根节点或body之下的标记节点对象(node)。每一个标记节点对象之下都有一个名为ChildNodes的集合,它包含了“直属于本节点下的标记”,就象是文件目录,根目录下的子目录……举个例子: 
     HELLO 001  
    在上面的网