0

我对 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();
    }
}
}
4

1 回答 1

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 的内容已经改变,因为它现在包含日历小部件,您可以从中提取详细信息。

知道什么时候会得到一个全新的 HtmlPage 可能会有点令人困惑,但通常只有当您在浏览器中看到一个全新的页面时才会这样。我从未尝试过针对 Gmail 之类的东西使用 HtmlUnit,但我怀疑您可能只处理一个 HtmlPage 对象,并且一切都发生在其中。

于 2010-03-19T16:56:08.867 回答