htmlunit抓取动态网页(何为Ajax动态网页,我想不用我多说了吧 )
优采云 发布时间: 2021-11-15 12:10htmlunit抓取动态网页(何为Ajax动态网页,我想不用我多说了吧
)
什么是 Ajax 动态网页?我想我不需要多说了。如果你连 Ajax 是什么都不知道,那么你应该先去谷歌学习 Ajax。为形象起见,这里以抓取本网页为例进行说明。网页链接如下:
很明显,我们要爬取的数据是
打开谷歌浏览器的开发者工具,我们会发现其实是Ajax动态加载的,通过jsonp跨域方法返回的。分析如图:
由此可以推断,部分分页信息是通过javaScript动态插入到DOM中的。如果单纯使用HttpClient之类的工具来模拟Http请求获取网页信息,你得到的网页内容是不完整的。HtmlUnit 可以做到。
OK,回到正题,也许你是第一次听说HtmlUnit,也许你很久以前就听说过它,但我仍然认为官方的解释是最权威的,我不会盲目的。看图:
总之一句话,HtmlUnit其实就是一个方便测试人员进行功能测试的测试工具。可以模拟谷歌Chrome、火狐、Internet Explorer等常见主流浏览器的行为。废话不多说,直接上demo:
/**
* 上海证券交易所数据抓取测试
* @since 1.0
* @author Lanxiaowei@citic-finance.com
* @date 2015-8-27下午6:16:14
*
*/
public class ShangHaiStockTest {
public static void main(String[] args) throws Exception {
downloadListPage();
}
public static void downloadListPage() throws Exception {
WebClient webClient = new WebClient(BrowserVersion.FIREFOX_38);
webClient.getOptions().setCssEnabled(false);
webClient.getOptions().setJavaScriptEnabled(true);
webClient.getOptions().setActiveXNative(false);
webClient.getOptions().setAppletEnabled(false);
webClient.getOptions().setRedirectEnabled(false);
webClient.getOptions().setThrowExceptionOnFailingStatusCode(false);
webClient.getOptions().setThrowExceptionOnScriptError(false);
webClient.getOptions().setUseInsecureSSL(false);
webClient.getOptions().setTimeout(10000000);
webClient.setAjaxController(new NicelyResynchronizingAjaxController());
int totalPage = 22;
boolean first = true;
HtmlPage page = null;
do {
if(first) {
page = (HtmlPage)webClient.getPage("http://www.sse.com.cn/assortment/stock/list/name/");
FileUtils.writeFile(page.asXml(), "C:/shh/list/" + totalPage + ".html", "UTF-8", false);
first = false;
} else {
HtmlAnchor anchor = null;
if(totalPage == 22 -1) {
anchor = (HtmlAnchor) page.getHtmlElementById("xsgf_next");
} else {
anchor = (HtmlAnchor) page.getHtmlElementById("dateList_container_next");
}
page = (HtmlPage) anchor.click();
FileUtils.writeFile(page.asXml(), "C:/shh/list/" + totalPage + ".html", "UTF-8", false);
}
totalPage--;
} while(totalPage > 0);
//关闭模拟窗口
webClient.closeAllWindows();
}
}
重点:
1.webClient.getOptions().setJavaScriptEnabled(true);
启用 JavaScript
2.webClient.setAjaxController(new NicelyResynchronizingAjaxController());
设置 Ajax 异步处理控制器以启用 Ajax 支持
3.webClient.getOptions().setThrowExceptionOnFailingStatusCode(false);
webClient.getOptions().setThrowExceptionOnScriptError(false);
这两句话非常重要。前者表示当发生Http错误时,程序不会抛出异常继续执行,后者表示在JavaScript执行中发生异常时,将被忽略,否则Java代码会直接抛出异常,程序将被中断。
演示代码演示了如何使用代码模拟点击“下一页”超链接进行分页,获取每个页面的网页内容,然后写入磁盘指定目录。程序很简单,希望能有个好的开始。程序依赖的jar包如图: