복붙노트

[SCALA] 이 자바 스크립트에 의해으로 업데이트 한 후 변경된 HTML 콘텐츠를 가져 오기? (HtmlUnit과)

SCALA

이 자바 스크립트에 의해으로 업데이트 한 후 변경된 HTML 콘텐츠를 가져 오기? (HtmlUnit과)

나는 몇 가지 문제 자바 스크립트를 업데이트 한 후 일부 HTML의 내용을 얻는 방법을 알아내는 데 문제.

특히, 나는 미국 해군 관측소 마스터 시계의 현재 시간을 얻기 위해 노력하고있어. 그것은 현재 시간을 표시하는 USNOclk의 ID와 H1 요소를 갖는다.

페이지가 처음로드는,이 요소는 다음 현재 시간에 자바 스크립트 차기 업데이트를 통해를 "...로드"를 표시하기 위해 설정 한 경우

function showTime()
    {
        document.getElementById('USNOclk').innerHTML="Loading...<br />";
        xmlHttp=GetXmlHttpObject();
        if (xmlHttp==null){
            document.getElementById('USNOclk').innerHTML="Sorry, browser incapatible. <BR />";
            return;
        } 
        refresher = 0;
        startResponse = new Date().getTime();
        var url="http://tycho.usno.navy.mil/cgi-bin/time.pl?n="+ startResponse;
        xmlHttp.onreadystatechange=stateChanged;
        xmlHttp.open("GET",url,true);
        xmlHttp.send(null);
    }  

그래서, 문제는 업데이트 된 시간을 얻을하는 방법을 잘 모르겠어요 것입니다. 내가 요소를 검사 할 때, 나는 "로드하는 중 ..."를 참조 H1 요소의 내용으로.

나는 이중 JavaScript가 활성화되어 있음을 확인했지만, 나는이 물건을 업데이트를 시작하기 위해 자바 스크립트 시간을 줄 것이라고 기대뿐만 아니라 웹 클라이언트에 waitForBackgroundJavaScript 함수를 호출 시도했습니다. 그러나 아직로서 성공하지.

import com.gargoylesoftware.htmlunit._
import com.gargoylesoftware.htmlunit.html.HtmlPage

object AtomicTime {

  def main(args: Array[String]): Unit = {
    val url = "http://tycho.usno.navy.mil/what.html"
    val client = new WebClient(BrowserVersion.CHROME)

    println(client.isJavaScriptEnabled()) // returns true
    client.waitForBackgroundJavaScript(10000)
//    client.waitForBackgroundJavaScriptStartingBefore(10000) //tried this one too without success
    var response: HtmlPage = client.getPage(url)
    println(response.asText())
  }
}

어떻게 HTML을 업데이트 할 수있는 자바 스크립트를 실행할 수 있습니까?

해결법

  1. ==============================

    1.나는 그것을 알아!

    나는 그것을 알아!

    HtmlPage 객체는 쇼 타임 스크립트를 킥오프하는 데 사용할 수있는 executeJavaScript (String)를 가지고있다. 스크립트가 실제로 시작되면 waitForBackgroundJavaScript 관련 될 때 다음, 그입니다.

    내가 함께 결국 코드 :

    import com.gargoylesoftware.htmlunit._
    import com.gargoylesoftware.htmlunit.html.HtmlPage
    import com.gargoylesoftware.htmlunit.html.DomElement
    
    object AtomicTime {
    
      def main(args: Array[String]): Unit = {
        val url = "http://tycho.usno.navy.mil/what.html"
        val client = new WebClient(BrowserVersion.CHROME)
    
        var response: HtmlPage = client.getPage(url)
        response.executeJavaScript("showTime")
    
        printf("Current AtomicTime: %s", getUpdatedRespose(response, client))
      }
    
      def getUpdatedRespose(page: HtmlPage, client: WebClient): String = {
        while (page.getElementById("USNOclk").asText() == "Loading...") {
          client.waitForBackgroundJavaScript(200)
        }
        return page.getElementById("USNOclk").asText()
      }
    }
    
  2. ==============================

    2.waitForBackgroundJavaScript 방법은 그것이 실험이라고 언급 할 가치가 좋은 대안이 될 것으로 보인다 있지만. 당신은 JavaDoc을 그 상태에있는 것을 볼 수 있습니다 :

    waitForBackgroundJavaScript 방법은 그것이 실험이라고 언급 할 가치가 좋은 대안이 될 것으로 보인다 있지만. 당신은 JavaDoc을 그 상태에있는 것을 볼 수 있습니다 :

    그래서 나는 약간 더 복잡한 접근 방식으로 이동하는 것이 좋습니다 :

    int amountOfTries = 10;
    while (amountOfTries > 0 && CONDITION) {
        amountOfTries--;
        synchronized (page) {
            page.wait(1000);
        }
    }
    

    amountOfTries 조건이 요청과 문제의 어떤 종류가 있었다 경우, 적절한 조치를 취할 수있다합니다. 그렇지 않으면, 당신은 무한 루프에 자기를 그만 둘 것이다. 그주의하십시오.

    그런 다음 당신은 당신의 실제 상태와 조건을 교체해야합니다. 이 경우는

    page.getElementById("USNOclk").asText().equals("Loading...")
    

    즉, 상기 코드는 조건을 검사한다 무엇은 10 초의 최대 초당 진정한되어있다.

    물론, 더 나은 접근 방식은 서로 다른 조건에서 로직을 재사용 할 수 있도록 별도의 방법으로이 오류 검사 동작을 추출하는 것입니다.

  3. from https://stackoverflow.com/questions/17843521/get-the-changed-html-content-after-its-updated-by-javascript-htmlunit by cc-by-sa and MIT license