var _gaq = _gaq || []; _gaq.push(['_setAccount', 'UA-333696-1']); _gaq.push(['_trackPageview']); _gaq.push(['_trackPageLoadTime']); (function() { var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true; ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js'; var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s); })();
  • 2008年10月04日

    Web自动化(1)

    分类:

    浏览器内网页的自动化都是通过组件对象模型(COM)完成的。不同的是,微软用的是Microsoft COM(通过MSHTML.dllCOM接口),而Mozilla则用的是类似MSCOMXPCOM(Cross Platform Component Object Model),从它的全称能看到该技术能够跨平台。想要访问Mozilla XPCOM库的应用程序使用一个叫做XPConnect的特殊XPCOM层,它把此库反射进JavaScript,它把前端粘住XPCOM中基于C++C编程语言的组件,于是XPConnect允许JavaScript对象直接访问和操作XPCOM对象,也允许JavaScript对象通过XPCOM接口来调用XPCOM对象。因而,MozillaJavaScript编写事件,用XUL(XML User Interface Language)/html编写界面。最新的WatiN提供了对Firefox浏览器的支持,其实现为利用Telnet类库连接到Mozilla的扩展模块JSSh(源码),以通过TCP/IP建立同正在运行的Mozilla进程的JavaScript shell连接。

     

    Mozilla公司使用Gecko作为其旗下浏览器的渲染引擎,它提供了对微软MSAA(Microsoft Active Accessibility)的核心IAccessible接口的支持。由于MSAA仅是DOM的子集,因而又额外提供了的三个接口:ISimpleDOMDocumentISimpleDOMNodeISimpleDOMText,详见Gecko Info for Windows Accessibility Vendors。其中ISimpleDOMNode提供以节点单位的实际解析的文档结构,ISimpleDOMText提供以字符为单位的滚动的矩形块信息,ISimpleDOMDocument包含基本文档信息。Mozilla的浏览器没有如MSIE一样提供对COM接口IDispatch的支持,所以使得自动化MSIE的程序无法支持Firefox

     

    Microsoft Internet Explorer中的网页自动化来说,其所有COM实现主要有以下几个方式:

    1.     脚本MSIE中的所有COM对象必须继承自IDispatch接口,这样才能提供脚本环境访问支持,这是因为IDispatch提供通用调用对象方法即用它的名称作为字符串,还不用知晓内存中它的二进制布局。如:

    [VBScript]

    <   Dim objRecordset

          Set objRecordset = Server.CreateObject("ADODB.Recordset")

          objRecordset.Open "SELECT * FROM MyTable", "MyConnectionString" >

    CreateObject首先调用CLSIDFromProgIDProdID来查找ADODBGUID,然后CreateObject调用CoCreateInstance来得到指向ADODB的指针(ADODB一定实现了IDispatch),脚本把它存储在变量objRecordset中;接着,脚本调用ADODBOpen,传递进查询语句:首先脚本引擎调用ADODBGetIDsOfNames来得到OpenDISPID,然后调用ADODBInvoke,传进该查询语句,详见The IDispatch InterfaceCOM in plain C, Part 2。此类比较有名的开源库是使用JavaScriptSelenium

     

    MSIE如何实现脚本访问?

    首先Document Object Model(DOM)是一种与平台和语言无关的标准对象模型以展现HTMLXML和其它相关格式,它定义了文档的逻辑结构和访问操控文档的方式。W3C设计DOM能被任何编程语言所使用,为此,W3C提供了一个精确的语言无关的DOM接口规范-OMGCORBA中定义的IDLW3C还提供了对JavaECMAScript语言的绑定。虽然W3CDOM规范中定义了接口,但各类浏览器对标准的实现不尽相同,于是就产生了差异,详见Comparison of layout engines。下表是MSHTMLDOM实现的小段对应:

    DOM Interface/Object

    Interface defined in MsHTML.h

    UUID defined in MsHTML.Idl

    Document

    IHTMEDocument

    3050f6c9-98b5-11cf-bb82-00aa00bdce0b

    IHTMEDocument2

    3050f485-98b5-11cf-bb82-00aa00bdce0b

    从上表能看到,正因为MSIE默认实现了DOM,所以脚本在使用DOM对象时,不需要如上面脚本那样显示调用COM对象,只需要直接使用即可。如:

    <<script type="text/javascript">>

    <<!--

    function sayHello()

    {

     var theirname=document.myForm.userName.value;

     if (theirname !="")

      alert("Hello "+theirname+"!");

     else

      alert("Don't be shy.");

    }

    //-->>

    <</script>>

     

    其次,MSIEActive脚本宿主。于是,MSIE才能同脚本引擎交互。搜索Windows注册表项JavaScript?versionJscriptLiveScript(注:JavaScript以前的名称)下的CLSID,发现它们全部相同,并且该CLSID对应的文件为jscript.dll,其下实现种类有Active Scripting EngineActive Scripting Engine with Parsing,详见Active ScriptingDebug Active Scripting,可以看到Windows下的脚本都继承自IUnknown接口。Active脚本引擎是一个COM组件,它实现了脚本的接口并理解如何解析脚本语言语法,它带有定制的COM对象集DLL,使用Active脚本引擎的应用程序叫做Active脚本宿主;应用程序为了同该引擎交互,必须实现IActiveScriptSite对象,以调用脚本引擎实现的方法,详见COM in plain C, Part 6Building Scriptable Applications by hosting JScript。以下脚本调用COM接口:

    [JScript]

    var req = new ActiveXObject("Microsoft.XMLHTTP");

    var xmlHttpReq = new ActiveXObject("MSXML2.XMLHTTP");

    var source = new ActiveXObject('Microsoft.XMLDOM');

    表中的Microsoft.XMLHTTPMSXML2.XMLHTTPMicrosoft.XMLDOMProgID能在注册表HKCR下找到其对应的CLSID

     

    基于以上两点,脚本才得以在MSIE环境中进行网页的操控。

    分享到: