HTMLUnit不等待Javascript

我有一个基于GWT的页面,我想使用HtmlUnit为它创build一个HTML快照。 该页面使用产品上的Ajax / JavaScript信息进行加载,因此,大约1秒钟之后将出现“加载…”消息,然后显示内容。

问题是,HtmlUnit似乎没有捕获的信息,我所得到的是“加载…”跨度。

下面是一个HtmlUnit的实验代码,我试图给它足够的时间来等待数据的加载,但它似乎没有改变任何东西,我仍然无法捕获由GWT JavaScript加载的数据。

WebClient webClient = new WebClient(); webClient.setJavaScriptEnabled(true); webClient.setThrowExceptionOnScriptError(false); webClient.setAjaxController(new NicelyResynchronizingAjaxController()); WebRequest request = new WebRequest(new URL("<my_url>")); HtmlPage page = webClient.getPage(request); int i = webClient.waitForBackgroundJavaScript(1000); while (i > 0) { i = webClient.waitForBackgroundJavaScript(1000); if (i == 0) { break; } synchronized (page) { System.out.println("wait"); page.wait(500); } } webClient.getAjaxController().processSynchron(page, request, false); System.out.println(page.asXml()); 

有任何想法吗…?

感谢您的回应。 其实我本来应该早点报告我自己find了解决办法。 显然,当用FF初始化WebClient时:

 WebClient webClient = new WebClient(BrowserVersion.FIREFOX_3_6); 

这似乎是工作。 当使用默认构造函数初始化WebClient时,默认使用IE7,我猜FF对Ajax有更好的支持,并且是推荐使用的模拟器。

我相信默认情况下NicelyResynchronizingAjaxController只会重新同步由用户操作引起的AJAX调用,通过跟踪它来自哪个线程。 也许GWT生成的JavaScript被NicelyResynchronizingAjaxController不想等待的其他线程调用。

尝试声明您自己的AjaxController与所有内容同步,而不pipe源于哪个线程:

 webClient.setAjaxController(new AjaxController(){ @Override public boolean processSynchron(HtmlPage page, WebRequest request, boolean async) { return true; } }); 

正如文档所述, waitForBackgroundJavaScript是实验性的:

实验API:可能会在下一个版本中更改,可能还不完美!

无论使用的是什么BrowserVersion ,下一个方法一直适用于我:

 int tries = 5; // Amount of tries to avoid infinite loop while (tries > 0 && aCondition) { tries--; synchronized(page) { page.wait(2000); // How often to check } } 

注意aCondition是你正在检查的任何东西。 例如:

 page.getElementById("loading-text-element").asText().equals("Loading...") 

迄今为止提供的解决scheme都没有为我工作。 我结束了与丹Alvizu的解决scheme +我自己的黑客:

 private WebClient webClient = new WebClient(); public void scrapPage() { makeWebClientWaitThroughJavaScriptLoadings(); HtmlPage page = login(); //do something that causes JavaScript loading waitOutLoading(page); } private void makeWebClientWaitThroughJavaScriptLoadings() { webClient.setAjaxController(new AjaxController(){ @Override public boolean processSynchron(HtmlPage page, WebRequest request, boolean async) { return true; } }); } private void waitOutLoading(HtmlPage page) { while(page.asText().contains("Please wait while loading!")){ webClient.waitForBackgroundJavaScript(100); } } 

不用说,“请稍候,加载!” 应该replace为正在加载页面时显示的任何文本。 如果没有文本,也许有一种方法来检查是否存在一些gif(如果使用的话)。 当然,如果你感觉冒险,你可以简单地提供足够的毫秒数。