我是HtmlUnit的新手,我在使用HtmlImageInput.click()获取表单时遇到了一些麻烦。当我调用该方法时,似乎没有任何事情发生,没有表单提交,没有到服务器的往返,或任何事情,据我所知。该方法立即返回,返回当前页面。
没有附加到图像输入的Javascript事件处理程序。它只是一个普通的老香草图像输入,没有什么特别的。加载页面时,输入最初设置为禁用,然后在用户与页面中的某些AJAXy元素交互时启用。但是当我点击输入时,它已经被启用了,所以我认为这不是一个AJAX问题。
有人知道发生了什么事吗?粘贴在下面的可运行源代码。
谢谢, 马修
import java.io.*;
import java.util.*;
import com.gargoylesoftware.htmlunit.*;
import com.gargoylesoftware.htmlunit.html.*;
import org.w3c.dom.*;
public class Test {
public static void main(String args[]) {
try {
WebClient webClient = new WebClient(BrowserVersion.INTERNET_EXPLORER_7);
webClient.setThrowExceptionOnScriptError(false);
HtmlPage page = webClient.getPage("http://us.megabus.com");
System.out.println("got the page");
HtmlForm form = page.getFormByName("ctl01");
System.out.println("got the form");
HtmlSelect select = form.getSelectByName("SearchAndBuy1$ddlLeavingFrom");
select.click();
System.out.println("clicked the select");
HtmlOption option = select.getOptionByValue("13");
option.click();
System.out.println("clicked the option...going to sleep");
try { Thread.sleep(15000); } catch(InterruptedException e) {}
select = form.getSelectByName("SearchAndBuy1$ddlTravellingTo");
select.click();
System.out.println("clicked the select 2");
option = select.getOptionByValue("37");
option.click();
System.out.println("clicked the option 2...going to sleep");
try { Thread.sleep(15000); } catch(InterruptedException e) {}
HtmlImage image = (HtmlImage)page.getElementById("SearchAndBuy1_imgOutboundDate");
image.click();
System.out.println("clicked the image");
String month = "April";
String date = "09";
HtmlTable table = (HtmlTable)page.getElementById("SearchAndBuy1_calendarOutboundDate");
HtmlTableRow row = ((HtmlTable)table.getCellAt(0, 0).getChildElements().iterator().next()).getRow(0);
String monthString = row.getCell(1).getTextContent();
monthString = monthString.substring(0, monthString.indexOf(' '));
while(!monthString.equals(month)) {
row.getCell(2).getChildElements().iterator().next().click();
System.out.println("clicked to go to the next month");
try { Thread.sleep(15000); } catch(InterruptedException e) {}
table = (HtmlTable)page.getElementById("SearchAndBuy1_calendarOutboundDate");
row = ((HtmlTable)table.getCellAt(0, 0).getChildElements().iterator().next()).getRow(0);
monthString = row.getCell(1).getTextContent();
monthString = monthString.substring(0, monthString.indexOf(' '));
}
DomNodeList<HtmlElement> aList = table.getElementsByTagName("a");
for (int i = 0; i < aList.size(); i++) {
HtmlAnchor anchor = (HtmlAnchor)aList.get(i);
if (anchor.getAttribute("title").equals(DomElement.ATTRIBUTE_NOT_DEFINED) || anchor.getAttribute("title").equals(DomElement.ATTRIBUTE_VALUE_EMPTY))
throw new RuntimeException("DomElement ATTRIBUTE_NOT_DEFINED or ATTRIBUTE_VALUE_EMPTY");
if (anchor.getAttribute("title").equals(month + " " + date)) {
anchor.click();
try { Thread.sleep(15000); } catch(InterruptedException e) {}
break;
}
}
HtmlImageInput imageInput = (HtmlImageInput)page.getElementByName("SearchAndBuy1$btnSearch");
page = (HtmlPage)imageInput.click();
System.out.println("clicked search button");
} catch(FailingHttpStatusCodeException e) {
e.printStackTrace();
} catch(IOException e) {
e.printStackTrace();
} catch(ElementNotFoundException e) {
e.printStackTrace();
} catch(IndexOutOfBoundsException e) {
e.printStackTrace();
}
}
}
答案 0 :(得分:0)
该图像不是输入字段,它只是一个普通的旧图像:
<img id="SearchAndBuy1_imgOutboundDate" disabled="disabled" alt="calendar"
CausesValidation="False" src="images/icon_calendar.gif" style="border-width:0px;" />
那里没有指定JS处理程序,因此必须将它们附加到别处,并且它们似乎位于页面的底部:
Sys.Application.add_init(function() {
$create(AjaxControlToolkit.PopupControlBehavior,
{"PopupControlID":"SearchAndBuy1_panelOutboundDate","Position":3,"dynamicServicePath":"/default.aspx","id":"SearchAndBuy1_pceImageOutboundDate"}, null, null, $get("SearchAndBuy1_imgOutboundDate"));
});
当你的程序点击图像时,没有表单提交,只是一个AJAX调用(大概),所以你是对的,你没有得到新页面。但是,正如您的代码证明的那样(我只是使用调试器运行它),HtmlPage的内容已经改变,因为它现在包含日历小部件,您可以从中提取详细信息。
知道什么时候你会得到一个新的Html网页可能有点令人困惑,但通常只有当你在浏览器中看到一个全新的页面时才会这样。我从来没有尝试过像HtmlUnit那样的Gmail,但我怀疑你可能只会处理一个HtmlPage对象,而且一切都在其中。