java - HTMLUnit input.click() 未返回单击应加载的站点

标签 java html click htmlunit

我正在尝试让机器人使用 HTMLUnit 随机填写表单。 到目前为止我所得到的:

WebClient client = new WebClient(BrowserVersion.CHROME);
    client.getOptions().setTimeout(60000);
    client.getOptions().setRedirectEnabled(true);
    client.getOptions().setJavaScriptEnabled(true);
    client.getOptions().setThrowExceptionOnFailingStatusCode(false);
    client.getOptions().setThrowExceptionOnScriptError(false);
    client.getOptions().setCssEnabled(false);
    client.getOptions().setUseInsecureSSL(true);

    client.setAjaxController(new NicelyResynchronizingAjaxController());

最后一行应该让 AJAX 在后台工作,剩下的就是简单的浏览器配置。

我编写了一种方法来正确执行对 DOMElement 的单击,并在后台进行日志记录和正确等待执行:

public static HtmlPage clickCorrectly(DomElement e, WebClient client) throws IOException {

    Main_Win.log("-------------------------------------");
    Main_Win.log("Clicking correctly: " + e);
    Main_Win.log("Background JS: " + client.waitForBackgroundJavaScript(30000));
    Main_Win.log("Click return: " + e.click());
    Main_Win.log("Background JS: " + client.waitForBackgroundJavaScript(30000));
    WebWindow tmpWebWindow = client.getCurrentWindow();
    Main_Win.log("Current Window: " + tmpWebWindow);
    Main_Win.log("Returning Enclosed Page: " + tmpWebWindow.getEnclosedPage());
    Main_Win.log("Parent Page: " + tmpWebWindow.getParentWindow());
    Main_Win.log("Top level Page: " + tmpWebWindow.getTopWindow());
    Main_Win.log("-------------------------------------");
    return (HtmlPage) tmpWebWindow.getEnclosedPage(); 
}

这对于我的登录过程非常有用。我单击登录按钮,输入我的凭据,然后提交。页面保持不变。因此单击不会更改 page 后面的对象多变的。稍后我尝试单击一个实际上是 anchor 标记的按钮:

<a class="btn btn-primary participate-link" data-id="116582" href="javascript:;" onclick="participateSurvey(116582, 'https://www.soscisurvey.de/SprachassistentenG3B/', '')">Jetzt teilnehmen</a>

我通过 XPath 获取 anchor 元素:

page.getByXPath("//a[@class='btn btn-primary participate-link']")

然后我将其转换为正确的元素:

HtmlAnchor a = (HtmlAnchor) o;

后来我像这样调用点击:

clickCorrectly(a, client)

这工作得很好。当我在 Firefox 中手动执行此操作时,我正在接收在浏览器中加载的页面。

现在来解决我的问题:

List<DomNode> elements = new ArrayList<DomNode>();
        elements.addAll(page.getElementsByTagName("input"));
        elements.addAll(page.getElementsByTagName("button"));

这些为我提供了我想要处理的所有元素。我正在检查 3 个案例:

  1. DomNode<input>类型为属性 "submit"
  2. DomNode<input>类型为属性 "button"
  3. DomNode<button>

    if(i.getTypeAttribute().equalsIgnoreCase("submit")) {
    
            if(i.toString().contains("weiter") || i.toString().contains("Weiter")){
    
                Main_Win.log("LOGGING BUTTON RETURN PAGE--------");
                Main_Win.log("Page before click: " + page);
                page = Main.clickCorrectly(i, client);
                Main_Win.log("Page after click: " + page);
                Main_Win.log("END LOGGING BUTTON RETURN PAGE--------");
    
                return true;
            }
        }
    

“Weiter”是德语,意思是“继续”。我正在对所有 3 个案例进行这样的检查。当您查看日志时,现在发生的情况会更清楚:

enter image description here

正如您所看到的,前后页面是不同的。 理论上,浏览器现在应该处理不同的页面,因为我将页面变量设置为单击的返回值。 在我的循环的下一次迭代中,前一个 URL 被处理,而不是我通过单击实现的 URL,尽管我将页面设置为它,并且循环每次循环时都会重新获取所有页面内容。我不明白为什么会发生这种情况。 为了更好地理解,以下是整个类(class):

https://pastebin.com/1wxdwUKS

最终目标是获得调查的最后一页,其中没有继续按钮。 对这么长的帖子感到抱歉,感谢您的宝贵时间!

最佳答案

所以实际上引用的重点就是问题所在。无论出于何种原因,HtmlPage 对象都没有通过引用传递......我不知道为什么,但这确实花费了我一生的时间。我会将这个问题留给其他有同样问题的人。

我通过将其传递给全局静态变量来解决它:

public static HtmlPage page = null;

并且只需在开始时复制一次:

AutoAnswer.page = pageCPY;

希望这会为某人节省很多时间:D 感谢您的阅读!

关于java - HTMLUnit input.click() 未返回单击应加载的站点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59344723/

相关文章:

php/html : One auto variable from one php file to another

javascript - 获取可见表行的大小

c# - DataGridView CheckBox 单元格/列事件

java - 为什么 ;没有显示任何异常?

java - 如何强制设置类型以创建泛型实例?

java - 关闭套接字连接

java - GlassFish 安全领域、Active Directory 和推荐

javascript - 我的第一个 Node.js 服务器:加载资源失败:net::ERR_INCOMPLETE_CHUNKED_ENCODING

javascript - 如何: Simulate click OK in WebBrowser alert/messagebox that initiated by a JavaScript?(德尔福)

python - 单击 Selenium Python 中 div 下拉列表中的标签,没有任何效果