htmlunit: отправьте форму POST и получите ответ - PullRequest
0 голосов
/ 01 октября 2019

Веб-сайт: 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 --- sep 30, 2019 8: 39: 15 PM com.gargoylesoftware.htmlunit.IncorrectnessListenerImpl notify ADVERTENCIA: Обнаружен устаревший тип контента: 'application / x-javascript'. 30 сентября 2019 20:39:21 com.gargoylesoftware.htmlunit.IncorrectnessListenerImpl notify ADVERTENCIA: обнаружен устаревший тип содержимого: 'application / x-javascript'. 30 сентября 2019 20:39:21 com.gargoylesoftware.htmlunit.javascript.DefaultJavaScriptErrorListener scriptException GRAVE: ошибка при выполнении JavaScript ======= ИСКЛЮЧЕНИЕ START ======== EcmaError: lineNumber = [0]column = [0] lineSource = [function () {] name = [TypeError] sourceName = [загрузить событие для HtmlBody [] в http://www.sunat.gob.pe/cl-ti-itmrconsruc/jcrS00Alias] 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());
        }
    }

Я с нетерпением жду возвращения успешного запроса.

1 Ответ

0 голосов
/ 03 октября 2019

Давайте начнем с чего-то общего:

Для настройки клиента, пожалуйста, установите только те опции, которые вам действительно нужны. По умолчанию он ведет себя как настоящий браузер, например, нет необходимости включать куки.

Есть некоторые предупреждения, которые вы можете игнорировать

Невозможно вызвать метод "goRefresh" из undefined

Это потому, что 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 (была странная ошибка, введенная 10 лет назад), которая теперь исправлена.

Надеюсь, это поможет.

...