基于HtmlUnit的转换网关的调研

一、前言:

目前大部分移动终端(手机)对javascript支持程度不高,这使得Web网站上很多交互操作无法无缝地迁移到手机上,只有部分高端手机(如IPHONE)除外,目前对javascript的解决策略无外乎三种,即富客户端的B/S结构、中等客户端的C/S结构和一般客户端的S结构。

三种策略相比,第一种对客户端功能要求比较高,相当于将PC浏览器移植到手机上,不仅对客户端硬件要求高,而且移植复杂度比较大;第二种策略,客户端完成一部分javascript的解析,服务端完成一部分解析,二者通过协作,完成脚本的支持,这种策略需要定义一套交互的协议,较少了客户端的开发工作量,同时对服务端的要求也不高,现阶段比较实用;第三种策略,全部javascript的解析工作都集中在服务端进行,客户端收到的响应中不包含javascript,这种策略对服务端处理过程要求比较高,同时需要定义客户端触发脚本的策略,但是这种策略之下,客户端与服务端进行的交互较少,有助于减少流量。

三种策略分别代表了三个阶段,策略三可以作为策略一、二的初级阶段,有了服务端对脚本的支持,才可能有策略二中服务端跟客户端的合作,有了策略一、二的积累,才最终实现脱离服务端的策略一的实现。

本文档主要针对如何在服务端支持javascript对HtmlUnit工具进行了调研,看能否将这个Java版的浏览器集成到服务端用于脚本的解析。

二、主要工作:

1.以HtmlUnit在页面自动化测试以及在搜索引擎方面的应用为切入点,熟悉了该工具的功能。

2.编写了测试代码,获取了HtmlUnit对javascript解析的耗时情况

3.总结了HtmlUnit应用于服务端脚本解析的下一步工作

下面将编写的测试代码贴出来:

    
try
		{
			//创建浏览器,可以选择IE、FF等等
		    WebClient client = new WebClient( BrowserVersion.INTERNET_EXPLORER_8 ,"192.168.8.175", 28089 );
		    //获取某网站页面
		    client.setThrowExceptionOnScriptError( false );
		    client.setCssEnabled( false );
		    
		    long start = System.currentTimeMillis();
		    HtmlPage page = client.getPage("http://www.qingke800.com/index.jsp");
		    System.out.println( "GetPage Cost Time : " + ( System.currentTimeMillis() - start ) + " ms" );
		    for( int i = 0; i < 3; i ++ )
		    {
		    	start = System.currentTimeMillis();
		    	page = client.getPage( "http://www.qingke800.com/index.jsp" );
		    	System.out.println( "GetPage" + i + "Cost Time : " + (System.currentTimeMillis() - start ) + "ms" );
		    	start = System.currentTimeMillis();
			    List<HtmlAnchor> anchors = (List<HtmlAnchor>) page.getByXPath( ".//*[@id='con_three_1']/div[2]/dl[1]/dd[2]/a" );
	
			    HtmlAnchor anchor = anchors.get( 0 );
	//		    System.out.println( anchor.getAttribute( "href" ) );
			    HtmlPage resultPage = anchor.click();
			    System.out.println( "Click " + i + "Cost Time : " + ( System.currentTimeMillis() - start ) + " ms" );
//			    System.out.println( "Result Page is : " + resultPage.getWebResponse().getContentAsString() );
		    }		    
		}
		catch( Exception e )
		{
			e.printStackTrace();
		}

这段代码主要测试HtmlUnit在获取页面、执行脚本生成结果页面的效率,HtmlUnit获取页面以及页面中的js代码是通过一个HTTP网关(192.168.8.175:28089),为了排除其他因素的影响,该网关将link标签、iframe标签、img标签进行了过滤,执行结果如下:

GetPageCostTime:54835ms

GetPage0CostTime:22667ms

Click0CostTime:22637ms

GetPage1CostTime:24415ms

Click1CostTime:24119ms

GetPage2CostTime:30265ms

Click2CostTime:22153ms

这里从网关的日志可以看出HtmlUnit具有本地缓存功能,第一次从一个HTML页面中获取了js文件之后,再次刷新时不会重新请求该js,由此可以看出若js文件存储在本地,

联网获取页面时间t1+页面解析生成DOM时间t2+脚本执行时间t3大约等于22s

而与此同时,我也进行了脚本执行时间的估计,具体方法是使用简单的javascript文件(不触发联网),则响应时间如下:

GetPageCostTime:31434ms

GetPage0CostTime:21280ms

Click0CostTime:141ms

GetPage1CostTime:20343ms

Click1CostTime:111ms

GetPage2CostTime:20233ms

Click2CostTime:110ms

由此可以推断,联网获取页面时间t1+页面解析生成DOM时间t2=20s

脚本执行时间t3大约为110ms

这里可以看出,脚本执行并不需要多少时间,关键在于页面获取以及生成DOM。

三、下一步工作:

1.优化DOM生成策略,从源页面规模、DOM生成方面

2.深入研究HtmlUnit的脚本解析和执行策略,看能否可以将脚本执行独立出来

相关推荐