10

在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?

4

2 回答 2

13

我想到了!

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()
  }
}
于 2013-07-24T21:19:09.437 回答
1

尽管该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几秒钟。

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

于 2013-10-23T19:58:01.450 回答