通过Javascript更新后获取更改后的HTML内容? (的HtmlUnit)
我有一些麻烦,搞清楚如何获得一些HTML的内容后, JavaScript已经更新。
具体而言,我试图从美国海军天文台主时钟获得当前时间。 它有一个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); }
所以,问题是我不知道如何获得更新的时间。 当我检查元素时,我看到“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
秒。
当然,更好的方法是将这种错误检查行为提取到一个单独的方法中,以便您可以在不同的条件下重用逻辑。