网站:http://www.sunat.gob.pe/cl-ti-itmrconsruc/jcrS00Alias
它有2帧,

一种以POST形式:http://www.sunat.gob.pe/cl-ti-itmrconsruc/frameCriterioBusqueda.jsp

另一个框架显示结果:http://www.sunat.gob.pe/cl-ti-itmrconsruc/frameResultadoBusqueda.html

在Apache Netbeans中进行测试会向我发送错误消息:

--- exec-maven-plugin:1.5.0:exec(default-cli)@ htmunit ---
2019年9月30日8:39:15 com.gargoylesoftware.htmlunit.IncorrectnessListenerImpl通知
ADVERTENCIA:遇到过时的内容类型:'application / x-javascript'。
2019年9月30日8:39:21 PM com.gargoylesoftware.htmlunit.IncorrectnessListenerImpl通知
ADVERTENCIA:遇到过时的内容类型:'application / x-javascript'。
2019年9月30日8:39:21 PM com.gargoylesoftware.htmlunit.javascript.DefaultJavaScriptErrorListener scriptException
GRAVE:JavaScript执行期间出错
=======例外开始========
EcmaError:lineNumber = [0]列= [0] lineSource = [function(){] name = [TypeError] sourceName = [在http://www.sunat.gob.pe/cl-ti-itmrconsruc/jcrS00Alias]中加载HtmlBody []的事件] message = [TypeError:无法调用方法的“ goRefresh”未定义]
com.gargoylesoftware.htmlunit.ScriptException:TypeError:无法调用未定义的方法“ goRefresh”

我的进步:


public static void main(String[] args) {
        // TODO code application logic here

        try {
            String url = "http://www.sunat.gob.pe/cl-ti-itmrconsruc/frameCriterioBusqueda.jsp";
            final WebClient webClient = new WebClient(BrowserVersion.CHROME);
            webClient.getOptions().setJavaScriptEnabled(true);
            webClient.getOptions().setCssEnabled(false);
            webClient.getCookieManager().setCookiesEnabled(true);
            webClient.setAjaxController(new NicelyResynchronizingAjaxController());
            webClient.getOptions().setThrowExceptionOnScriptError(false);

            HtmlPage htmlpage = webClient.getPage(url);

            //webClient.waitForBackgroundJavaScript(10000);
            //CookieManager coo = webClient.getCookieManager();
            //Cookie cookie = coo.getCookie("TS01c75c6f");
            //System.out.println(cookie.getValue());

            HtmlForm htmlForm = htmlpage.getElementByName("mainForm");
            //htmlForm.setActionAttribute("jcrS00Alias");
            HtmlTextInput input1 = htmlForm.getInputByName("search1");
            HtmlTextInput input2 = htmlForm.getInputByName("codigo");
            input1.setText("10468790497");

            HtmlHiddenInput hidden = (HtmlHiddenInput)htmlForm.getInputByName("accion");
            hidden.setValueAttribute("consPorRuc");

            HtmlImage image = htmlpage.<HtmlImage>getFirstByXPath("//img[@src='captcha?accion=image']");
            ImageReader img = image.getImageReader();
            BufferedImage buf = img.read(0);
            // Show image
            ImageIcon icon = new ImageIcon(buf);
            String codigo = JOptionPane.showInputDialog(null, icon, "Captcha image", JOptionPane.PLAIN_MESSAGE);
            input2.setText(codigo);

            HtmlButton boton = (HtmlButton) htmlpage.createElement("button");
            boton.setAttribute("type", "submit");
            htmlForm.appendChild(boton);

            htmlpage = boton.click();

            System.out.println(htmlpage.asXml().toString());

        } catch (Exception ex) {
            System.out.println(ex.getMessage());
        }
    }


我期待着返回成功的查询。

最佳答案

让我们从一般的东西开始:

对于客户端的设置,请仅设置您真正需要的选项。默认情况是行为类似于真实的浏览器,无需例如启用Cookie。

有一些警告您可以忽略


无法调用未定义的方法“ goRefresh”


这是因为框架中的js(在您的情况下为结果框架文档)试图从另一个框架中调用函数来更新验证码。但是您没有加载整个框架集-因此无法以预期的方式实现此功能。

为了获得结果,您必须获取另一帧的内容。

这段代码似乎有效:

    // work with the whole frameset
    String url = "http://www.sunat.gob.pe/cl-ti-itmrconsruc/jcrS00Alias";

    try (final WebClient webClient = new WebClient(BrowserVersion.FIREFOX_60)) {
        // do not stop in case of js errors
        webClient.getOptions().setThrowExceptionOnScriptError(false);

        HtmlPage frameset = webClient.getPage(url);
        HtmlPage searchPage = (HtmlPage) frameset.getFrameByName("leftFrame").getEnclosedPage();

        HtmlForm htmlForm = searchPage.getElementByName("mainForm");

        // set search field
        HtmlTextInput input1 = htmlForm.getInputByName("search1");
        input1.setText("10468790497");

        // process captcha
        HtmlImage image = searchPage.<HtmlImage>getFirstByXPath("//img[@src='captcha?accion=image']");
        ImageReader img = image.getImageReader();
        BufferedImage buf = img.read(0);
        ImageIcon icon = new ImageIcon(buf);
        String codigo = JOptionPane.showInputDialog(null, icon, "Captcha image", JOptionPane.PLAIN_MESSAGE);
        HtmlTextInput input2 = htmlForm.getInputByName("codigo");
        input2.setText(codigo);

        // click the button
        HtmlElement boton = htmlForm.getElementsByAttribute("input", "value", "Buscar").get(0);
        boton.click();

        // and get the result
        HtmlPage resultPage = (HtmlPage) frameset.getFrameByName("mainFrame").getEnclosedPage();
        System.out.println(resultPage.asText());
    }


但是,您需要最新的HtmlUnit快照才能运行此快照,而没有js错误(十年前引入了一个奇怪的错误),该错误现已修复。

希望能有所帮助。

关于java - htmlunit:发送POST表单并检索响应,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/58177201/

10-13 09:12