我在查找 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?
答案 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
秒。
当然,更好的方法是将此错误检查行为提取到一个单独的方法中,以便您可以在不同条件下重用逻辑。