HtmlUnit中AJAX执行的问题

一、概述

    HtmlUnit,不多介绍,Java中的开源无UI“浏览器”。在一些小的爬虫项目中想要爬取数据,现在很多网站使用大量ajax,普通爬虫无法获取js生成的内容。HtmlUnit对JS、AJAX支持比较好,可以得到最终呈现的HTML源代码数据。


二、方案

   1、第一步,我们需要配置WebClient,如下代码

WebClient webClient=new WebClient(BrowserVersion.FIREFOX_17);//设置浏览器的User-Agent
webClient.setJavaScriptTimeout(10000);//设置JS执行的超时时间
webClient.getOptions().setThrowExceptionOnScriptError(false);//当JS执行出错的时候是否抛出异常
webClient.getOptions().setThrowExceptionOnFailingStatusCode(false);//当HTTP的状态非200时是否抛出异常
webClient.getOptions().setTimeout(30000);//设置“浏览器”的请求超时时间
ebClient.getOptions().setCssEnabled(false);//是否启用CSS
webClient.getOptions().setJavaScriptEnabled(true); //很重要,启用JS
webClient.waitForBackgroundJavaScript(30000);//设置JS后台等待执行时间
webClient.setAjaxController(new NicelyResynchronizingAjaxController());//很重要,设置支持AJAX

 当我们设置后以上选项后,依然无法得到AJAX执行完成后HTML页面呈现的数据。针对此,官网FQA给出了回答:

Nothing happens when using HtmlUnit with AJAX, although page works correctly in browsers. What's wrong?

The main thread using HtmlUnit may be finishing execution before allowing background threads to run. You have a couple of options:

webClient.setAjaxController(new NicelyResynchronizingAjaxController()); will tell your WebClient instance to re-synchronize asynchronous XHR.

webClient.waitForBackgroundJavaScript(10000); or webClient.waitForBackgroundJavaScriptStartingBefore(10000); just after getting the page and before manipulating it.

Explicitly wait for a condition that is expected be fulfilled when your JavaScript runs, e.g.

       //try 20 times to wait .5 second each for filling the page.
        for (int i = 0; i < 20; i++) {
            if (condition_to_happen_after_js_execution) {
                break;
            }
            synchronized (page) {
                page.wait(500);
            }
        }


三、示例代码
HtmlPage resultPage =  (HtmlPage)page;
HtmlElement resultData = resultPage.getBody().getElementById("hdivResultPanel");
List<HtmlElement> columns = resultData.getElementsByAttribute("div", "class", "avt_column");
//try 20 times to wait .5 second each for filling the page.
for (int i = 0; i < 20; i++) {
     if (columns.size()>0) {
           logger.info("等待ajax执行完毕");
           break;
     }
      synchronized (resultPage) {
           page.wait(500);
      }
}		
//解析来,可以针对resultPage进行数据解析工作……




转载于:https://my.oschina.net/hc24/blog/383301

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值