Get the changed HTML content after it's updated by Javascript? (htmlunit)

拈花ヽ惹草 提交于 2019-11-26 13:44:25

I figured it out!

HtmlPage objects have an executeJavaScript(String) which can be used to kick off the showTime script. Then, once the script has actually started, that's when waitForBackgroundJavaScript becomes relevant.

The code I ended up with:

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

Although the waitForBackgroundJavaScript method seems to be a good alternative it's worth mentioning that it is experimental. You can see that in the JavaDocs that state:

Experimental API: May be changed in next release and may not yet work perfectly!

So I recommend to go for a slightly more complex approach:

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

Note the amountOfTries condition is there to take appropriate action if there has been some kind of issue with the request. Otherwise, you will end up getting your self into an infinite loop. Be careful with that.

Then you should replace CONDITION with your actual condition. In this case it is

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

In short, what the code above does is checking for the condition to become true each second for a maximum of 10 seconds.

Of course, a better approach would be to extract this error checking behavior into a separate method so that you can reuse the logic on different conditions.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!