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
在上面的网页例子里,HTML标记是文档的根节点,是Document的Childnodes集合中的一个成员(还是要提请注意,Document不是节点,是另一种类型对象:上一级文档,但它可以有下级节点集合,正如磁盘可以有下级目录,但它本身不是目录),BODY是根节点的ChildNodes集合中的一个成员,而DIV和P两个节点则是BODY的ChildNodes集合中的两个成员,同样也有自已的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是从1开始计数的,其次,它用的计数属性是Length而不是Count。
除了ChildNodes集合,大家在网页文档对象中还常见到的就是很大气的一种集合:All集合,这是“最糊涂”的一种集合,文档和各级节点都带有这个集合,正如这个名字所示,它是不分层次的,但用起来也很方便:
……. Set doc=ieA.Document Set xCols=doc.All ;取得文档中的所有节点集合 Set xbCols=doc.body.All ;取得body节点下所有的节点集合
虽然任何标记节点都有ALL集合,但我们还是喜欢用DOCUMENT的ALL,原因无它,文档最大,一锅烩的ALL找起来也最合适。 ALL查找是有条件的:如果这个标记没有ID,你无法查到它的名字:
HELLO 001 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集合,因为大部分网页的数据提交都是通过FORM标记提交的,因此FORMS集合在没有网页中FORM标记没有ID标记或ID标记重复的情况下,可以用来区分不同的FORM节点
Set myForms=doc.Forms ‘取得所有的FORM标记 Set frmX=myForms.item(0) ‘第1个FORM
FORM标记节点代表的对象是很多朋友关心的内容――在网页对象中,它可以发送数据到服务器,使服务器刷新网页(实际上是服务器按某个格式约定发回数据),我们可以把网页的FORM看成是一个远程的函数调用接口,FORM标记中的ACTION指向的URL地址就是函数入口,而FORM标记内的各个INPUT标记节点就是函数的参数,当发出FORM.Submit方法时,就是远程调用函数了,在服务器端,诸如ASP,PHP就是老老实实找FORM的参数,不管你是用GET还是POST:
frmX.submit ‘相当于用户在页面上按下FORM的发送按键
至于它的参数,也就是INPUT标记们的值,我们当然可以自已修改,一般使用value属性即可,具体可参考DHTML手册。但对于RADIO类型的INPUT,按同一个NAME为一组,你不要被迷惑了,仍旧当成是几个INPUT标记即可。也就是说,假定RADIO类型的NAME为“mod”,从文档对象的角度来看,使用
SET 对象=oDoc.All("mod")
或者它的直接领导上一级FORM对象引出
SET 对象=ofrm.elements("mod")
我们得到的对象,都是一个同名RADIO标记的集合,而不是单个标记。所以,要访问MOD也不算很难,先得到RADIO集合,然后令这个集合中两个中的任一个CHECKED为TRUE即可:
set xMod=ofrm.elements("mod") xMod(0).checked=true '选中第一个,如果要选第二个,用xMod(1).checked=true
注意不是用xMod(n).value=1来选,你设定某个项的checked为true,则其它radio自动为false,value属性达不到这个要求。
在使用submit时,网页设计程序会默认提交按钮的Name属性也为submit,这样会导致 form对象.submit无效,此时修改提交铵钮的Name属性即可,或是使用 form对象.elements("submit").click来摸拟客户提交。而使用超链接与表单对象的click摸拟,我们可以避开一些网站的检测手段,此时的程序类似于Office应用中的“宏”,它起到了代替人工作重复工作的作用。
另外,因为IE默认安全性问题,会有阻止脚本运行、不让弹出新窗口等问题的存在,可以通过加入可信站点并设置选项来回避安全性问题。对于弹出新窗口也可以设置form的target为"_blank"来刷新当前页面,但要注意,重刷新本页面以后,原来相关的DOCUMENT对象都不算数了,如果还要引用这个页面上的对象,要重新指定。
在具有框架的页面中,我们需要注意一个框架相当于一个window控件,要处理框架内页的元素,需要以类似的方法来判断是否加载完毕并设置Document对象:
Do Until ieA.document.frames(i).document.ReadyState="Complete" DoEvents Loop set doc=ieA.Document.frames(i).Document
在使用IE的自动化对象(InternetExplorer.Application)或WebBrowser对象(Microsoft Internet Controls)获取网页源码有一个不太好的地方,就是在获取源码的同时会获取到图片等媒体信息,这会使获取源码的效率大大降低,因此我们可以使用XMLHTTP对象(或VB中的Inet控件)来获取源码,然后置入IE或WebBrowser对象中进行DOM树方式处理。如 WebBrowser1.Silent = True '屏蔽脚本错误提示,以防止弹出式对话框等麻烦 WebBrowser1.Navigate "about:blank" '先清空 Do Until WebBrowser1.ReadyState = 4 '等待加载完毕 DoEvents Loop WebBrowser1.Document.write shtml 'shtml为已经通过其它方式取得的网页源码 Do Until WebBrowser1.ReadyState = 4 '等待加载完毕 DoEvents Loop Set doc = WebBrowser1.Document 'vbscript中使用HTMLDocument文档对象 SET doc='CreateObject("htmlfile") doc.write shtml 'shtml为已经通过其它方式取得的网页源码 'vbscript中使用xmlDocument文档对象 SET doc=CreateObject("MSXML2.DOMDocument") '或set doc=CreateObject("Microsoft.XMLDocument") doc.loadxml shtml '使用shtml=doc.load(sURL) 可以获得源码
如果你分析了已经存在的网页,想从一个空白页面(ABOUT:BLANK)用VBA“凭空”生成FORM和INPUT节点,光凭上面的方法还不够,我们还要“创造节点”(createElement)并连入文档对应的位置(appendChild),但这已经是另一个问题了。
发表评论
-
Flex加载多个Module时出现“TypeError: Error #1034: 强制转换类型失败”错误
2012-01-20 09:56 968Flex加载多个Module时出现“TypeError: Er ... -
Flex 笔记心得连载中
2012-01-20 09:56 723Flex 笔记心得连载中 2010年08月03日 获取焦 ... -
[tamarin系列之9] 在线的eval
2012-01-20 09:56 584[tamarin系列之9] 在线的eval 2010年06月 ... -
Flash务实主义――Loading
2012-01-20 09:56 532Flash务实主义――Loading ... -
Flex动态加载swc和swf中的class
2012-01-20 09:54 842Flex动态加载swc和swf中的class 2011年05 ... -
VB 刷网站代码
2012-01-19 15:00 587VB 刷网站代码 2011年03 ... -
批处理+VBS脚本实现纯文本代码格式化输出
2012-01-19 15:00 601批处理+VBS脚本实现纯文 ... -
ASP文本文档(txt)相关操作代码
2012-01-19 15:00 690ASP文本文档(txt)相关操作代码 2011年04月22日 ... -
为方便自己看网络小说,自己写个txt按章节分段的小程序
2012-01-19 15:00 919为方便自己看网络小说,自己写个txt按章节分段的小程序 20 ... -
2011-3-9
2012-01-19 15:00 4512011-3-9 2011年03月09日 REG2BAT ... -
OpenGL开发库的详细介绍
2012-01-17 04:43 517OpenGL开发库的详细介绍 ... -
转载:OpenGL显示文字
2012-01-17 04:43 541转载:OpenGL显示文字 2010年07月03日 本课 ... -
VS2005配置OpenGL
2012-01-17 04:43 1000VS2005配置OpenGL 2011年06月24日 昨 ... -
OpenGL的安装
2012-01-17 04:43 624OpenGL的安装 2010年06月20 ... -
opengl
2012-01-17 04:43 685opengl 2010年11月17日 ... -
C#面试题集锦(你值得拥有!)
2012-01-16 03:37 1106C#面试题集锦(你值得拥 ... -
ASP.Net考试复习资料
2012-01-16 03:37 903ASP.Net考试复习资料 2011 ... -
javascript:history.go()和History.back()的区别
2012-01-16 03:37 780javascript:history.go()和History ... -
经典的串口调试助手源代码(一)
2012-01-16 03:37 647经典的串口调试助手源代码(一) 2011年05月26日 ...
相关推荐
文档对象模型中文手册预览版 (IE5.0+)
供提问使用,Microsoft JScript 运行时错误: 缺少对象 Microsoft JScript 运行时错误: 缺少对象
目前的 ASP 版本总共提供了六个内建对象,分别是Request对象、Response对象、Server对象、Session对象、Application对象及ObjectContext对象,其各自功能简述如下: Request对象:负责从客户机接收信息; Response ...
ASP.NET01页面对象模型 ASP.NET01页面对象模型 ASP.NET01页面对象模型 ASP.NET01页面对象模型
ASP+3.0的对象模型
题(1) 跳马(1) Asp.net(1) NET(1) 网页设计配色常识(1) DOM文档对象中文手册(1) Services(1) 题(1) 跳马(1) Asp.net(1) NET(1) 网页设计配色常识(1) DOM文档对象中文手册(1) Services(1)
本文讨论关于建立ASP.NET Web页的事件模型和转化为HTML的各个过程的细节。ASP.NET HTTP 运行时管理着把请求URL转换成一个页面类的具体实例的对象管道,接下来把这些实例转换成一般的HTML文本格式。本文对代表各个...
ASP网站小偷源码
asp使用xmldom对象解析xml文件示例。
asp 小偷程序2.0,方便个人,解放双手。远程采集资源,内容保存数据库,图片保存本地。 1根据html标签,自定义截取范围 2偷取页面内容自动保存到数据库 3第一图自动生成缩略图 4远程图片自动保存到本地
开良ASP小偷生成器
ASP.NET core 5.0文档PDF(含目录,共5453页)。摘要: ASP.NET Core 文档及新增内容 ASP.NET 比较 .NET Core 和 .NET Framework 入门新增功能 5.0 版中的新增功能 3.1/3.0/2.2/2.1/2.0/1.1 版中的新增功能 教程Web ...
超级完美,直接上传到空间就可以用,界面美观大方,程序自动搜集最新电影,自动更新,无需维护,源码只有100K,功能强大,并可以添加属于自己的广告,欢迎下载交流。
《JScript 语言参考》中文版 asp ado中文版 ASP 6 abject中文版 Asp.net技术文档+CHM第二版 ...文档对象模型DOM帮助文档 HTML中文手册 javascript中文版 Jsp帮助文档中文版 微软Vbscript手册中文版
java初学者项目:太阳系模型源代码 本项目适用于初学者,主要用来帮助初学者学习练习java中awt的一些内容,但最重要的是通过本项目让初学者接触到oop即面向对象程序设计和相似代码的封装
ASP.NET网页一般由三部分组成,这三个部分如下所示。 q 可视元素:包括HTML,标记,服务器空间。 q 页面逻辑元素:包括事件处理程序和代码。 q designer.cs页文件:用来为页面的控件做初始化工作,一般只有ASP.NET...
笑话小偷v1.0.2 asp版使用说明: 1、直接解压 传至网站根目录即可(支持2级目录)。 2、网站配置(关键字配置) 编辑 inc下Const.asp文件。 程序说明: 1、show.asp文件为另外小偷地址页面。
ASP中实现小偷程序
适合DOM XML初学者。详细的注释,让您能一目了然
伪静态版ASP文章小偷(采集)程序伪静态版ASP文章小偷(采集)程序