[英]HTMLUnit doesn't wait for Javascript
我有一个基于GWT的页面,我想使用HtmlUnit为它创建一个HTML快照。 页面使用产品上的Ajax / JavaScript信息加载,因此大约1秒钟就会出现Loading ...消息,然后会显示内容。
问题是HtmlUnit似乎没有捕获信息,我得到的只是“Loading ...”范围。
下面是一个带有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());
有任何想法吗...?
谢谢你的回复。 实际上我应该早点报告这个问题,我自己找到了解决方案。 显然在使用FF初始化WebClient时:
WebClient webClient = new WebClient(BrowserVersion.FIREFOX_3_6);
它似乎工作。 当使用默认构造函数初始化WebClient时,它默认使用IE7,我猜FF对Ajax有更好的支持,是推荐使用的模拟器。
我相信默认情况下, NicelyResynchronizingAjaxController
只会通过跟踪源自哪个线程来重新同步由用户操作引起的AJAX调用。 也许GWT生成的JavaScript正被NicelyResynchronizingAjaxController
不想等待的其他一些线程调用。
尝试声明自己的AjaxController与所有内容同步,无论原始线程如何:
webClient.setAjaxController(new AjaxController(){
@Override
public boolean processSynchron(HtmlPage page, WebRequest request, boolean async)
{
return true;
}
});
到目前为止,没有一个解决方案能为我提供解决方 我最终得到了Dan Alvizu的解决方案 +我自己的黑客:
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);
}
}
不用说,“请等待加载!” 应该在页面加载时替换为显示的任何文本。 如果没有文本,也许有办法检查是否存在某些gif(如果使用的话)。 当然,如果你喜欢冒险,你可以简单地提供足够大的毫秒值。
正如文档所述, waitForBackgroundJavaScript
是实验性的:
实验API:可能会在下一个版本中更改,但可能尚未完美运行!
无论使用的是BrowserVersion
,下一种方法对我来说一直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...")
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.