通过Javascript更新后获取更改后的HTML内容? (的HtmlUnit)

时间:2013-07-24 19:46:38

标签: java scala htmlunit

我在查找 javascript更新后如何获取某些HTML 的内容时遇到了一些麻烦。

具体来说,我正试图从US Naval Observatory Master Clock获取当前时间。它有h1元素ID USNOclk,其中显示当前时间。

首次加载页面时,此元素设置为显示“正在加载...”,然后javascript启动并通过

将其更新为当前时间
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上的webclient函数,并希望它能让javascript有时间开始更新内容。但是,到目前为止还没有成功。

我的当前代码:

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())
  }
}

如何触发javascript来更新HTML?

2 个答案:

答案 0 :(得分:8)

我明白了!

HtmlPage个对象有一个executeJavaScript(String),可以用来启动showTime脚本。然后,一旦脚本实际开始,那就是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()
  }
}

答案 1 :(得分:2)

虽然waitForBackgroundJavaScript方法似乎是一个不错的选择,但值得一提的是它是实验性的。您可以在JavaDocs中看到:

  

实验API:可能会在下一个版本中更改,但可能尚未完美运行!

所以我建议采用稍微复杂的方法:

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

请注意,如果请求存在某种问题,amountOfTries条件可以采取适当的措施。否则,你最终会让自己陷入无限循环。小心。

然后你应该用你的实际情况替换CONDITION。在这种情况下,它是

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

简而言之,上面的代码所做的是检查条件每秒true,最多10秒。

当然,更好的方法是将此错误检查行为提取到一个单独的方法中,以便您可以在不同条件下重用逻辑。