簡體   English   中英

HTMLUnit不等待Javascript

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM