使用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;
此篇文章已被阅读4615 次