programing

HTMLU가 Javascript를 기다리지 않음

lovejava 2023. 8. 7. 22:15

HTMLU가 Javascript를 기다리지 않음

HtmlUnit을 사용하여 HTML 스냅샷을 만들고 싶은 GWT 기반 페이지가 있습니다.제품에 대한 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());

무슨 생각이라도...?

응답해 주셔서 감사합니다.사실 제가 직접 해결책을 찾았다고 더 빨리 보고했어야 했습니다.FF를 사용하여 Web Client를 초기화하는 경우:

WebClient webClient = new WebClient(BrowserVersion.FIREFOX_3_6);

효과가 있는 것 같습니다.기본 생성자로 WebClient를 초기화할 때 기본적으로 IE7을 사용하며 FF가 Ajax를 더 잘 지원하며 사용하기에 권장되는 에뮬레이터입니다.

나는 기본적으로 믿습니다.NicelyResynchronizingAjaxController는 사용자 작업으로 인해 발생한 AJAX 호출을 원본 스레드를 추적하여 다시 동기화합니다.아마도 GWT가 생성한 자바스크립트가 다른 스레드에 의해 호출되고 있을 것입니다.NicelyResynchronizingAjaxController기다리는 것을 원하지 않습니다.

원본 스레드에 관계없이 모든 것과 동기화하도록 Ajax 컨트롤러를 선언해 보십시오.

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

설명서에 나와 있듯이, 는 실험적인 것입니다.

실험 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당신이 확인하고 있는 것은 무엇입니까.EG:

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

지금까지 제공된 솔루션 중 어떤 것도 저에게 효과가 없었습니다.저는 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의 존재를 확인할 수 있는 방법이 있을 수 있습니다(사용되는 경우).물론, 여러분이 모험심을 느낀다면, 여러분은 그저 충분히 큰 밀리초 값을 제공할 수 있습니다.

언급URL : https://stackoverflow.com/questions/5555178/htmlunit-doesnt-wait-for-javascript