`
代号43
  • 浏览: 13117 次
社区版块
存档分类
最新评论

使用htmlunit实现带有Ajax复杂页面的静态化技术

    博客分类:
  • mvc
阅读更多

  1·最近项目要求要把网站的首页静态化,网站的首页是和多个jsp页面组成,整体显示的时候大概5000多行,比较困难的地方是很多地方由于做了jquery特效,所以当初直接使用$.ajax获取的数据,并直接生成的html.其中又包括了一些处理逻辑,如

if(0 == li.length){
				if(2==data.columncaption.length){//样式补位
					li = $('<li class="wordspacing" id="'+data.columnid+'li"><a href="#" class="pRound_tab">'+data.columncaption+'</a></li>');
				}else{
				li = $('<li id="'+data.columnid+'li"><a href="#" >'+data.columncaption+'</a></li>');
				}
				$('#BookrackUL').append(li);
				var div=$('<div class="pane secondpane"><a class="prev browse left"></a><div class="scrollable w657" id="scrollable"><div class="items" id="'+id+'fdiv" ><div id="'+id+'div'+k+'"><p class="picBox mr35 ml15" id="'+id+'p"> <a href="<%=request.getContextPath()%>/ContentAction_getContent.action?id='+data.contentid+'" ><img src="'+data.contentsourceurl+'" width="100px" height="130px" alt="" /></a><strong>'+data_caption+'</strong><a href="<%=request.getContextPath()%>/Page/knowmore.jsp?root='+data.columnid+'" class="more"><img src="images/more.gif" alt="" /></a></p></div></div></div><a class="next browse right"></a></div>');
				$('#BookrackDiv').append(div); 
				j=1;
				
				
			}else{
				if(0==j%5){//第一次创建一个div
					k=k+1;
					var div=$('<div id="'+id+'div'+k+'"><p class="picBox mr35 ml15"  id="'+id+'p"> <a href="<%=request.getContextPath()%>/ContentAction_getContent.action?id='+data.contentid+'" ><img src="'+data.contentsourceurl+'" width="100px" height="130px" alt="" /></a><strong>'+data_caption+'</strong><a href="<%=request.getContextPath()%>/Page/knowmore.jsp?root='+data.columnid+'" class="more"><img src="images/more.gif" alt="" /></a></p></div>');	
					$('#'+id+'fdiv').append(div);
				}else if(4==j%5){//样式调整
					var pp=$('<p class="picBox" id="'+id+'p"><a href="<%=request.getContextPath()%>/ContentAction_getContent.action?id='+data.contentid+'" ><img src="'+data.contentsourceurl+'" width="100px" height="130px" alt="" /></a><strong>'+data_caption+'</strong><a href="<%=request.getContextPath()%>/Page/knowmore.jsp?root='+data.columnid+'" class="more"><img src="images/more.gif" alt="" /></a></p>');
					$('#'+id+'div'+k+'').append(pp);
				}else{//其他正常
					var pp=$('<p class="picBox mr35" id="'+id+'p"><a href="<%=request.getContextPath()%>/ContentAction_getContent.action?id='+data.contentid+'" ><img src="'+data.contentsourceurl+'" width="100px" height="130px" alt="" /></a><strong>'+data_caption+'</strong><a href="<%=request.getContextPath()%>/Page/knowmore.jsp?root='+data.columnid+'" class="more"><img src="images/more.gif" alt="" /></a></p>');
					$('#'+id+'div'+k+'').append(pp);
				}
				j=j+1;
			}

原本是打算使用比较流行的freemaker来实现首页静态化,但以前没用过很难用freemaker标签实现这种效果.

  2·静态化还有一种思路就要采用HttpClient获取首页生成的html文件保存作为静态页,但是很不幸的,HttpClient无法执行js,所有使用ajax获取的数据都无法获取到,于是这种方式也行不通

  3·最后使用HtmlUnit.HtmlUnit的优势就是可以支持大部分js,对JQuery的支持也不错.大体思路就是先使用HtmlUnit获取执行完js的html,这个html生成的样式和html格式会出现一些问题.如果能满足需求则可以直接使用或者略加改动后使用.

如果这个html不能满足需求,那么就把它当做为静态数据来使用.这个时候我们先需要一个html模板文件,这个模板文件要保证首页的主题框架,然后从html按照各个div将数据填充进去.下面贴一些实现代码.

//创建一个可执行js,css,ajax的多功能WebClient
				WebClient multiWebClient = new WebClient(BrowserVersion.INTERNET_EXPLORER_8);
				multiWebClient.setJavaScriptEnabled(true);//执行JavaScript
				multiWebClient.setCssEnabled(true);//执行css
				multiWebClient.setAjaxController(new NicelyResynchronizingAjaxController());//设置ajax代理
				
				//创建一个普通的WebClient
				WebClient commmonWebClient = new WebClient(BrowserVersion.INTERNET_EXPLORER_8);
				commmonWebClient.setJavaScriptEnabled(false);
				commmonWebClient.setCssEnabled(false);
				
				//用多功能Client获取动态页面的html并执行完js后的页面
				URL dynamicUrl = new URL("http://localhost:30010/WebSite");
				HtmlPage dynamicPage = (HtmlPage) multiWebClient.getPage(dynamicUrl);
				
				//根据项目需要,使用普通Client加载首页模板(避免执行模板里面的js,这些js都是真正要浏览器查看的时候才会执行)
				URL constantUrl = new URL("http://localhost:30010/WebSite/wwwroot/indexTemple.html");
				HtmlPage htmlpage = (HtmlPage) commmonWebClient.getPage(constantUrl);
				HtmlElement body = htmlpage.getBody(); 
				
				/**
				 * 未详细测试的结论:getElementById一个元素只能取一次,取了之后再取就是空元素,其子也无法用getElementById取到
				 * 开始处理header
				 */
				appendChildren(body.getElementById("_static_nav"), dynamicPage.getElementById("_static_nav"));
				
				//开始处理_static_leftbox
				//处理图片滚动KSS_content
				appendChildren(body.getElementById("KinSlideshow"), dynamicPage.getElementById("KSS_content"));
				//处理最新电子书
				appendChildren(body.getElementById("e_bookDiv"), dynamicPage.getElementById("e_bookDiv"));
				
				//取出content
				HtmlElement content = body.getElementById("content");
				
				//开始处理_static_rightbox
				content.appendChild(dynamicPage.getElementById("_static_rightbox"));
				//添加div换行
				DomElement clearDiv = htmlpage.createElement("div");
				clearDiv.setAttribute("class", "clear");
				//一个DomElement貌似只能使用一次
				content.appendChild(clearDiv.cloneNode(true));
				
				//开始处理_static_bookshow
				content.appendChild(dynamicPage.getElementById("_static_bookshow"));
				content.appendChild(clearDiv.cloneNode(true));
				
				//开始处理_static_assistBox,secrecyRelevancediv,_static_optionBox
				content.appendChild(dynamicPage.getElementById("_static_assistBox"));
				content.appendChild(dynamicPage.getElementById("secrecyRelevancediv"));
				content.appendChild(dynamicPage.getElementById("_static_optionBox"));
				content.appendChild(clearDiv.cloneNode(true));
				
				//开始处理_static_bookShowA
				content.appendChild(dynamicPage.getElementById("_static_bookShowA"));
				content.appendChild(clearDiv.cloneNode(true));
				//开始处理_static_serve
				content.appendChild(dynamicPage.getElementById("_static_serve"));
				
				//开始处理footer
				body.appendChild(clearDiv.cloneNode(true));
				body.appendChild(dynamicPage.getElementById("_static_footer"));
				
				
				//处理错误
				String finalHtml =htmlpage.asXml().replace("<?xml version=\"1.0\" encoding=\"utf-8\"?>", "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">"); 
				finalHtml = finalHtml.replaceAll("<a class=\"prev browse left\"/>", "<a class=\"prev browse left\" ></a>");
				finalHtml = finalHtml.replaceAll("<a class=\"next browse right\"/>", "<a class=\"next browse right\" ></a>");
				finalHtml = finalHtml.replaceAll("<b/>", "<b></b>");
				finalHtml = finalHtml.replaceAll("scrollable_2", "scrollable");
				stringToFile(finalHtml,"E:\\WayOfGlory\\WebSite\\WebContent\\wwwroot\\indexHome.html");

   上面一段代码虽然不长,但实际上是个非常漫长的处理过程,从静态数据html中获取到的<div></div>经常会无法直接使用,这时就需要不断的和浏览器(比如chrome)生成的真正静态页进行比对.虽然过程很漫长,但总比无法实现要强.

   下面贴上刚刚使用了的两个小方法.

    	public DomElement appendChildren(DomElement target,DomElement source){
    		
			Iterator it = source.getChildElements().iterator();
			while(it.hasNext()){
				DomElement ele = (DomElement) it.next();
				target.appendChild(ele);
			}
    		return target;
    	}
    	
    	

    	public void stringToFile(String content,String path){
    		try {
				FileWriterWithEncoding fileWriter = new FileWriterWithEncoding(path,"utf-8");
				fileWriter.write(content);
				fileWriter.flush();
				fileWriter.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
    	}

   这种实现是自己瞎研究的,如果有哪位大虾有更好的方法,欢迎指点.

8
1
分享到:
评论
3 楼 yixiandave 2013-10-11  
保留ajax没什么问题吧。既然是异步请求就有异步请求的理由
2 楼 dagmom 2013-10-11  
其实保留部分ajax的东西未必就不好
1 楼 fykyx521 2013-10-11  
静态化不需要处理js吧,除非界面做的有点。。。  而且ajax 知道地址后台直接读取生称div直接嵌入首页就行了

相关推荐

    基于ApacheNutch和Htmlunit的扩展实现AJAX页面爬虫抓取解析插件nutch-htmlunit.zip

    基于Apache Nutch 1.8和Htmlunit组件,实现对于AJAX加载类型页面的完整页面内容抓取解析。 According to the implementation of Apache Nutch 1.8, we can't get dynamic ...

    基于Apache Nutch和Htmlunit的扩展实现AJAX页面爬虫抓取解析插件.zip

    【标题】"基于Apache Nutch和Htmlunit的扩展实现AJAX页面爬虫抓取解析插件.zip" 提供了一个深入的爬虫项目实例,旨在解决AJAX动态网页内容的抓取问题。Apache Nutch是一个开源的网络爬虫框架,而Htmlunit是一个无头...

    Htmlunit2.23-bin.zip

    然而,由于它是一种无头浏览器模拟,对于某些复杂的页面交互或特定的JavaScript库支持可能会有限,这时可能需要考虑使用更强大的工具,如Selenium WebDriver。 总之,HTMLUnit 2.23提供了一个强大且高效的工具,...

    htmlunit爬取动态页面jar包

    这个压缩包包含21个jar文件,这些文件是实现HTMLUnit功能所必需的依赖库,确保了在运行时对动态和静态页面的正确解析和支持。 HTMLUnit的核心在于它能够执行JavaScript,这对于爬取那些依赖JavaScript来加载内容的...

    通过htmlunit获取执行js代码后的html文档

    4. **执行JavaScript**:在页面加载后,你可以使用`executeJavaScript`方法执行任意JavaScript代码。这个方法返回一个`JavaScriptResult`对象,可以通过`asText`或`asDomNodeList`方法获取结果。 ```java String ...

    最新版HtmlUnit2.22含API文档

    总的来说,HtmlUnit 2.22为Java开发者提供了一个强大的工具,帮助他们在没有实际浏览器的情况下进行Web应用的测试和自动化,尤其适用于那些依赖JavaScript和Ajax技术的复杂应用。配合详尽的API文档,开发者可以更...

    htmlunit爬虫技术

    在“htmlunit爬虫技术”中,我们将深入探讨如何利用HTMLUnit来实现高效的网络爬虫。 HTMLUnit的核心特性包括: 1. **JavaScript支持**:HTMLUnit能够执行JavaScript代码,这对于许多动态加载内容的现代网站来说至...

    htmlunit-2.19-bin

    3. **JavaScript支持**:HTMLUnit的一大特点是它支持JavaScript执行,这意味着它可以处理动态加载的内容和页面交互,这对于测试复杂的Web应用至关重要。 4. **API使用**:HTMLUnit提供了一套丰富的Java API,允许...

    htmlunit-2.3..zip

    使用HTMLUnit进行单元测试时,你可以创建一个测试类,通过调用HTMLUnit提供的API来初始化一个WebClient对象,然后打开目标网页,查找并操作页面元素,最后检查结果是否符合预期。例如,你可以模拟点击按钮、填写表单...

    htmlunit爬虫技术jar包

    开发者只需要将这些jar文件添加到Java项目的类路径中,就可以开始使用HTMLUnit进行网页抓取和自动化测试。在实际应用中,你可能还需要根据具体需求,结合其他库如Jsoup(用于更简单的HTML解析)或Apache HttpClient...

    htmlunit依赖jar包

    HTMLUnit是一款功能强大的Java库,它模拟了一个无头Web浏览器,允许开发者在没有真实浏览器环境的情况下执行JavaScript,处理Ajax请求,以及与网页进行交互。这个库对于自动化测试、数据抓取和网页爬虫项目非常有用...

    传一个htmlunit依赖的jar包,官网所下

    接着,如果有JavaScript存在,HTMLUnit会使用内置的Rhino JavaScript引擎执行这些脚本,更新DOM树以反映动态变化的网页状态。这样,开发者可以通过HTMLUnit提供的API来访问和操作这个虚拟DOM,就像在实际浏览器中...

    htmlunit包

    3. **支持AJAX**:HTMLUnit可以处理异步加载的数据,这对于现代Web应用的测试至关重要,因为许多网页使用AJAX技术来更新内容。 4. **自动处理JavaScript错误**:HTMLUnit尝试在遇到JavaScript错误时继续执行,这样...

    htmlunit基本jar包

    HTMLUnit是一个Java库,它提供了一个无头浏览器模拟器,用于自动化Web页面的测试和交互。这个"htmlunit基本jar包"包含了运行HTMLUnit所需的所有核心组件,无需通过Maven来管理和依赖。这意味着用户可以直接在项目中...

    com.gargoylesoftware.htmlunit-2.29所需包

    HTMLUnit是一个Java库,它提供了一个无头浏览器模拟器,用于自动化Web页面的导航和交互。这个库在进行网络爬虫或自动化测试时非常有用,因为它可以解析HTML、执行JavaScript,甚至处理AJAX请求,而无需打开实际的...

    Htmlunit2.8开发文档

    - **Ajax 处理**:可以模拟异步请求,允许测试依赖Ajax技术的页面。 - **网络交互**:可以模拟HTTP和HTTPS协议,包括设置cookies、管理session等。 - **网页元素操作**:提供了API来选择和操作DOM元素,如点击...

    htmlunit-2.8(api文档).zip

    3. **AJAX支持**:HTMLUnit可以处理AJAX异步请求,使得开发者能够测试那些通过AJAX技术构建的动态网页。 4. **WebClient**:HTMLUnit的核心类`WebClient`提供了访问网页的基本功能,如打开URL,提交表单,执行...

    htmlunit 及其 依赖包

    HTMLUnit是一个功能强大的Java库,它模拟了一个无头Web浏览器,允许开发者进行自动化网页测试和网络爬虫工作。这个库的核心在于它能够解析HTML、执行JavaScript,并与网页上的元素进行交互,而无需真实地打开一个...

    htmlunit-2.36和htmlunit-2.50,包括关联文件

    这个库在进行HTTP请求时,尤其是上传或下载带有复杂内容类型的数据(如图片、文件等)时非常有用。它是HTMLUnit进行网络通信时的一个关键依赖,因为HTMLUnit可能需要发送或接收HTTP请求来加载和操作网页。 使用...

Global site tag (gtag.js) - Google Analytics