HtmlUnit: войдите в HtmlElement, когда клик не отвечает - PullRequest
0 голосов
/ 04 июля 2018

Привет, я впервые использую HtmlUnit [версия 2.31], я пытаюсь зайти на веб-страницу. Вот HTML-код:

<body>
    <div id="login">
        <div id="header">
            User Log In
        </div>
        <div id="error">Enter your credentials to login</div>
        <table>
            <tr>
                <th>Username</th>
                <td><input type="text" id="username" /></td>
            </tr>
            <tr>
                <th>Password</th>
                <td><input type="password" id="password" /></td>
            </tr>
        </table>
        <div id="buttons">
            <input type="button" value="Login" id="button" onclick="login();" />
        </div>
    </div>
</body>

Вот мой код:

 WebClient webClient = new WebClient(BrowserVersion.FIREFOX_52);
 webClient.getOptions().setJavaScriptEnabled(false);
 webClient.getOptions().setUseInsecureSSL(true);
 try{            
        HtmlPage page = webClient.getPage(url);
        String pageContent = page.asText();
        System.out.println(pageContent);
        HtmlButtonInput button = page.getFirstByXPath("//input[@type = 'button']");
     //I'm new to XPath, but I think this works okay


        HtmlTextInput name  = (HtmlTextInput) page.getElementById("username"); 
        HtmlPasswordInput pwd  = (HtmlPasswordInput) page.getElementById("password");

        System.out.println(name.getSelectedText());
        name.setValueAttribute(username);
        pwd.setValueAttribute(password);
        System.out.println(name.getSelectedText());

        HtmlPage loggedInPage = button.click();
        String pageContent2 = loggedInPage.asText();
        System.out.println("after logged in");
        System.out.println(pageContent2);

}

Обе страницы (до и после входа в систему) распечатаны одинаково. Так что я должен был сделать что-то не так здесь. Любая помощь будет оценена.

Редактировать 1: Я уже пробовал Thread.sleep (2000) после ввода имени пользователя и пароля и перед строкой нажатия

Редактировать 2: JS для входа в систему:

document.onkeypress = processKey;


function processKey(e) {
    if (null == e)
        e = window.event ;
    if (e.keyCode != 13) 
        return;
    $('button').click();
    return false;
}


function parseXMLTag(tag) {
    var value = '';
    if (tag && tag.firstChild != undefined) {
        value = tag.firstChild.nodeValue;
    }
    return value;
}


function login() {
    new Ajax.Request('/cti/api/admin/login.xml', {
        method: 'post',
        parameters: {username: $('username').value, password: $('password').value},
        onSuccess: function(transport) {
            var response = transport.responseXML;
            var success = parseXMLTag(response.firstChild.getElementsByTagName('success')[0]);
            var error = parseXMLTag(response.firstChild.getElementsByTagName('error')[0]);
            if (success == 1)
                document.location = 'main.html';
            else
                $('error').innerHTML = error;
        }
    }); 
}

Ответы [ 2 ]

0 голосов
/ 04 июля 2018

Поскольку вы не опубликовали URL-адрес, по которому вы звоните, я могу предоставить только некоторые подсказки.

Даже если HtmlUnit делает много магии за кулисами, вам необходимо общее понимание всех веб-технологий

Из кода похоже, что вход выполнен на основе Ajax; это имеет некоторые последствия:

  • Ajax требует включенного JavaScript (HtmlUnit по умолчанию)
  • Ajax является асинхронным - все действия (например, щелчок) в HtmlUnit синхронизированы, это означает, что вам нужно дождаться завершения вызова ajax
  • в вашем особом случае вызов ajax изменяет содержимое страницы в случае успеха путем перезагрузки страницы с использованием другого URL-адреса (document.location = 'main.html'). Как следствие вы должны обновить свою переменную страницы

Или в коде:

try (WebClient webClient = new WebClient(BrowserVersion.FIREFOX_52))
{
    webClient.getOptions().setUseInsecureSSL(true);

    HtmlPage page = webClient.getPage(url);
    String pageContent = page.asText();
    System.out.println(pageContent);

    HtmlButtonInput button = page.getFirstByXPath("//input[@type = 'button']");
    // to make sure you got the right element
    System.out.println(button.asXml());

    HtmlTextInput name  = (HtmlTextInput) page.getElementById("username"); 
    HtmlPasswordInput pwd  = (HtmlPasswordInput) page.getElementById("password");

    // use type() to simulate typing
    name.type(username);
    pwd.type(password);

    // no need to get the page here because this is still the one the
    // button is placed on
    button.click();

    // wait for ajax to do the job
    webClient.waitForBackgroundJavaScript(10000);


    // ok hopefully the job is done and the login was successfull
    // lets get the current page out of the current window
    HtmlPage loggedInPage = (HtmlPage) page.getEnclosingWindow().getTopWindow().getEnclosedPage();

    ...

    // check the result
    // you can also write this to a file and open it in a real browser
    // maybe the login was failing and there is an error message
    // rendered on this page
    System.out.println(loggedInPage.asXml());

}

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

0 голосов
/ 04 июля 2018

Я бы посоветовал вам попробовать:

 webClient.getOptions().setJavaScriptEnabled(true);
 webClient.getOptions().setRedirectEnabled(true);
...