我有这个项目,我需要使用一个站点从中获取数据。 所以问题是:使用htmlunit我用我的数据填充文本框,然后我按下使用ajax的锚点下载我需要的内容并动态更改HTML页面,在模态窗口中显示内容。但是我在锚点上使用.click()之后我得到了相同的页面,没有更新,在寻找解决方案之后我在网上找到了这个:
HtmlUnit将执行Ajax调用并将更新页面。只是 请注意,与常规页面加载不同,click()调用不会 等待Ajax请求的完成。它将继续前进 下一行代码马上。
这是我的代码:
final HtmlPage page = webClient.getPage("myUrl");
System.out.println(page.asXml());
final HtmlForm form = page.getFirstByXPath("//form[@action='myFormAction']");
final HtmlTextInput input = form.getInputByName("url");
input.setText(vacancyURL);
List<HtmlAnchor> anchors = page.getAnchors();
HtmlAnchor link = null;
for (HtmlAnchor anchor : anchors) {
String str = anchor.asText();
if (anchor.asText().equals("Start"))
link = anchor;
}
HtmlPage page2 = link.click(); //I think this is a problem
任何想法我如何点击锚点并等待ajax接收回复,并用数据填充页面(在浏览器上一切正常)?我真的需要帮助,任何想法?
答案 0 :(得分:1)
是的,你必须等待执行,最好是重试一段时间,直到页面没有更新(使用任何条件) 这是代码的例子
int input_length = page.getByXPath("//input").size();
int tries = 5;
while (tries > 0 && input_length < 12) { //you can change number of tries and condition according to your need
tries--;
synchronized (page) {
page.wait(2000); //wait
}
input_length = page.getByXPath("//input").size(); //input length is example of condtion
}
答案 1 :(得分:1)
我同意Tasawer,依靠状态/元素通常是件好事。
根据远程网站上的javascript,您还可以询问webclient有多少javscripts线程仍在进行中。例如:
int wait = 0;
int nbProcess = 1;
while (nbProcess > 0 && wait < 10) {
nbProcess = client.waitForBackgroundJavaScript(1000);
if (wait == 9) {
System.err.println("** needs more time ** ");
}
wait++;
}
警告:某些网站可以永久运行一个或多个脚本,因此最小nbProcess可以是1,2 ......
链接到javadoc
答案 2 :(得分:0)
page.wait
令人作呕......因为当ajax请求结束时你不会立即得到通知,会有延迟..
我的回答是使用方法
com.gargoylesoftware.htmlunit.javascript.background.JavaScriptJobManager#waitForJobs
调用示例:page.getEnclosingWindow().getJobManager().waitForJobs(1000);
页面是一种com.gargoylesoftware.htmlunit.html.HtmlPage
1000是timeoutMillis,表示你想要等待的最长时间