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

我有一些麻烦,搞清楚如何获得一些HTML的内容后, JavaScript已经更新。

具体而言,我试图从美国海军天文台主时钟获得当前时间。 它有一个h1元素,其IDUSNOclk ,显示当前时间。

当页面第一次加载时,这个元素被设置为显示“正在加载…”,然后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); } 

所以,问题是我不知道如何获得更新的时间。 当我检查元素时,我看到“Loading …”作为h1元素的内容。

我已经仔细检查,启用JavaScript,我已经尝试调用waitForBackgroundJavaScript函数,以及希望它会给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?

我想到了!

HtmlPage对象有一个可以用来启动showTime脚本的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() } } 

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

实验API:可能会在下一个版本中更改,可能还不完美!

所以我build议去做一个稍微复杂的方法:

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

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

那么你应该用你的实际状况来取代CONDITION 。 在这种情况下

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

总之,上面的代码是检查条件成为true每秒最多10秒。

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