如何在使用 java 设置用于屏幕抓取的表单值后调用 post 方法

How to call post method after setting the value of the form for screen scraping using java

背景: 我有一个网页 (.aspx) 有几个下拉列表 lists.The 列表值正在使用Ajax 根据上一个下拉列表的选择调用。选择所有下拉列表的值后,我们可以点击下载按钮,数据将根据下载的数据进行下载,我们需要执行一些其他操作。

我已经做了什么: 我可以通过正确调用 ajax 来设置下拉数据,但是发送 post 请求是个问题.这里是代码snippet/pseudo代码。

随意使用任何工具 java

public static void main(String[] args) throws FailingHttpStatusCodeException, IOException {
        final WebClient webClient = new WebClient(BrowserVersion.FIREFOX_17);


        WebRequest request = new WebRequest(new URL(DataDownloader.MY_URL),HttpMethod.POST);

        webClient.getOptions().setThrowExceptionOnScriptError(false);
        webClient.setJavaScriptTimeout(10000);
        webClient.getOptions().setJavaScriptEnabled(true);
        webClient.setAjaxController(new NicelyResynchronizingAjaxController());
        webClient.getOptions().setTimeout(10000);

        HtmlPage page = webClient.getPage(request);     

        HtmlSelect firstDd = (HtmlSelect) page.getElementById("dd1_id");
        List<HtmlOption> firstOption = firstDd.getOptions();
        firstDd.setSelectedAttribute(firstOption.get(2), true);
        webClient.waitForBackgroundJavaScript(3000);

        HtmlPage pgAfterFirstDd = (HtmlPage) webClient.getCurrentWindow().getEnclosedPage();
        HtmlSelect secondDd = (HtmlSelect) pgAfterFirstDd.getElementById("dd2_id");

        List<HtmlOption> secondOption = secondDd.getOptions();
        secondDd.setSelectedAttribute(secondOption.get(2), true);
        webClient.waitForBackgroundJavaScript(10000);
        //set the value for all other dropdowns


        HtmlPage finalpage = (HtmlPage) webClient.getCurrentWindow().getEnclosedPage();         
        HtmlForm form = finalpage.getHtmlElementById("aspnetForm");
        webClient.waitForBackgroundJavaScript(10000);


        request.setRequestBody("REQUESTBODY");
        Page redirectPage = webClient.getPage(request);

//       HtmlSubmitInput submitInput=form.getInputByName("btnSubmit");
//      submitInput.click();
        /*HtmlButton submitButton = (HtmlButton) pageAfterWard.createElement("btnSubmit");
        submitButton.setAttribute("type", "submit");
        form.appendChild(submitButton);

        HtmlPage nextPage = (HtmlPage) submitButton.click();*/
    }
final WebClient webClient = new WebClient(BrowserVersion.FIREFOX_17);

看来您使用的是旧版本,请使用最新版本。

WebRequest request = new WebRequest(new URL(DataDownloader.MY_URL),HttpMethod.POST);

对于 HtmlUnit,您通常不需要处理请求。想法是工作更多 'browser like'。使用类似 getPage(final URL url).

List<HtmlOption> firstOption = firstDd.getOptions();
firstDd.setSelectedAttribute(firstOption.get(2), true);

多做点工作'browser like'

firstOption.get(2)setSelected(true);

这将为您完成所有后台工作,例如为您取消选择其他选项和事件处理。

关于提交您的想法

 HtmlSubmitInput submitInput=form.getInputByName("btnSubmit");
 HtmlPage nextPage = submitInput.click();

看起来正确。也许您还需要等待。 如果您仍然有问题,您必须提供您正在使用的 URL 以使我们能够 reproduce/debug 您的案例。

正如您在 RBRi 的回答下的评论中提到的,您正在获得类型转换 error.can 请提及

  • 您收到的确切错误是什么
  • 您期待的 file/response 是什么类型。

因为代码对我来说看起来不错而且应该可以完美运行..

为什么要隐藏错误详细信息?有什么秘密吗?如果您喜欢有用的答案,则必须提供尽可能多的信息。 所以我做了一个大胆的猜测...

submitInput.click();

将 return PDF。在这种情况下,你必须做类似

的事情
Page pdfPage = submitInput.click();
WebResponse resp = pdfPage.getWebResponse();
if("application/pdf".equals(resp.getContentType())) {
    .... process the bytes
    .... resp.getContentAsStream()
}

HtmlUnit 有四种页面 HtmlPage/XmlPage/TextPage 和 UnexpectedPage。 PDF 或办公文档等二进制内容作为 UnexpectedPage 处理。处理此内容由您决定。