使用htmlunit抓取网页中ajax或者js动态生成的内容
Posted On 2016年12月9日
为什么要抓取ajax的内容?
1)并不一定必须要进行ajax的内容, 首先要确认你抓取的数据页面webpage是否包含了ajax或者js动态数据。 如果有动态的,则必须使用支持js解析的html 框架(其实就是类似浏览器)进行。
2. 如果纯粹的html数据解析,则直接用http client即可。
首先先列出用于测试的html页面。
test1.html 测试页面。 js代码直接写dom。
<html> <head><title>Test Page</title></head> <body> <script> document.write("<div>content generated by javascript!</div>"); </script> </body> </html>
test2.html 异步请求数据
<html> <head><title>Test Page</title></head> <body> <script> function get() { var xhttp = new XMLHttpRequest(); xhttp.onreadystatechange = function() { if (this.readyState == 4 && this.status == 200) { document.write(this.responseText); } }; xhttp.open("GET", "testcontent", true); xhttp.send(); } get(); </script> </body> </html>
异步请求数据,模拟异步请求有较长时间的延时。
<html> <head><title>Test Page</title></head> <body> <script> function get() { var xhttp = new XMLHttpRequest(); console.log("start xhr request"); xhttp.onreadystatechange = function() { if (this.readyState == 4 && this.status == 200) { //document.write(this.responseText); document.getElementById("demo").innerHTML = this.responseText; } }; xhttp.open("GET", "testcontent", true); xhttp.send(); } setTimeout(function(){ get(); }, 4000); console.log("set timed out !"); </script> <div id="demo"></div> </body> </html>
使用httpclient 直接读取html
String url = "http://qa.heika.com/dashboard/test2.html"; String returnJson = Request.Get(url).execute().returnContent().asString(); System.out.println(returnJson);
使用htmlunit 读取html(支持js解析)
final WebClient webClient = new WebClient(); final HtmlPage page = webClient.getPage("http://qa.heika.com/dashboard/test2.html"); // Assert.assertEquals("HtmlUnit - Welcome to HtmlUnit", page.getTitleText()); final String pageAsXml = page.asXml(); System.out.println(pageAsXml);
使用htmlunit读取html,(支持异步ajax执行)
final WebClient webClient = new WebClient(); //WebClient instance to re-synchronize asynchronous XHR. webClient.setAjaxController(new NicelyResynchronizingAjaxController()); //webClient.waitForBackgroundJavaScript(5000); final HtmlPage page = webClient.getPage("http://qa.heika.com/dashboard/test2.html"); // Assert.assertEquals("HtmlUnit - Welcome to HtmlUnit", page.getTitleText()); final String pageAsXml = page.asXml(); System.out.println(pageAsXml);
使用htmlunit读取html,设定page的等待时间,模拟ajax请求有较大的延时的情况(支持异步ajax执行)
final WebClient webClient = new WebClient(BrowserVersion.FIREFOX_38); //WebClient instance to re-synchronize asynchronous XHR. //webClient.setAjaxController(new NicelyResynchronizingAjaxController()); //webClient.waitForBackgroundJavaScript(5000); //webClient.waitForBackgroundJavaScriptStartingBefore(10000); HtmlPage page = webClient.getPage("http://qa.heika.com/dashboard/test3.html"); synchronized (page) { page.wait(5000); } // Assert.assertEquals("HtmlUnit - Welcome to HtmlUnit", page.getTitleText()); final String pageAsXml = page.asXml(); System.out.println(pageAsXml);
由上方的几个例子可以看出,htmlunit对ajax的支持是没有任何问题的,就如htmlunit官方所说的那样。
但是需要注意的是, ajax异步执行的内容如果包含document.write(); 的内容不会被htmlunit抓取到的page更新。 如果使用如下方式 新变更dom,却没发现问题。
document.getElementById("demo").innerHTML = this.responseText;
此篇文章已被阅读4114 次