TLDR:
我使用 HtmlUnit
headless 浏览器登录,网站将我重定向到一个页面,我必须单击提交按钮才能继续,但在 HtmlUnit
中找不到其元素。无法找到登录后点击它进入所需页面的方法。常规人工登录不存在此页面。
背景
我的学校有一个学习环境,我们可以订阅类(class)来下载类(class) Material 等。
当我刚刚开始学习 Java 类(class)时,我想我可以尝试看看是否可以制作一个 Java 应用程序,它可以登录并为我获取所有类(class) Material 。
我必须注意,此学习环境需要从类似于 Outlook 的 Microsoft 环境登录,但该环境是为大学定制的。也许这给了我登陆的页面应该是什么的线索。
我尝试过的
我查看了 HtmlUnit,似乎 headless 浏览器至少可以实现我的登录目标。我设置了一个 WebClient
并导航到该页面。
像这样:
final WebClient webClient = new WebClient(BrowserVersion.FIREFOX_60);
webClient.getOptions().setJavaScriptEnabled(true);
webClient.getCookieManager().setCookiesEnabled(true);
webClient.getOptions().setRedirectEnabled(true);
HtmlPage page = webClient.getPage(LOGIN_FORM_URL);
一切都很顺利,我进入了登录页面并隔离了表单并使用我的凭据填写了输入:
HtmlForm form = page.getForms().get(0);
HtmlEmailInput username = form.getInputByName("UserName");
HtmlPasswordInput pass = form.getInputByName("Password");
HtmlElement buttonElement = form.getElementsByTagName("span").get(1);
username.setValueAttribute(USERNAME);
pass.setValueAttribute(PASSWORD);
HtmlPage page2 = buttonElement.click();
问题
我本以为会被重定向到学习环境,但我却得到了一个奇怪的页面。 这是使用 page2.asXml()
打印时的结构:
<html>
<head>
<title>
Working...
</title>
</head>
<body>
<form method="POST" name="hiddenform" action="https://engine.surfconext.nl:443/authentication/sp/consume-assertion">
<input type="hidden" name="SAMLResponse" value="PHNhbWxwOl.... An insanely long value />
<noscript>
<p>Script is disabled. Click Submit to continue.</p><input type="submit" value="Submit" />
</noscript>
</form>
<script language="javascript">
//<![CDATA[
window.setTimeout('document.forms[0].submit()', 0);
//]]>
</script>
</body>
</html>
我一辈子都无法弄清楚如何单击 noscript 标记之间的输入。
我尝试使用 getElementsByTagName
查找提交输入,以便我可以模拟对其的点击,但它似乎甚至没有意识到它的存在。当我在 noscript 标记上使用 getChildElementCount()
时,它返回 0
。
我需要做一些特别的事情才能通过此页面吗?
请您参考如下方法:
我认为这个问题非常广泛,需要回答,但当您提供更多信息和发现时,我将更新答案。
免责声明:此答案仅用于教育目的。我不愿意帮助您构建网络抓取工具。至少不是免费的;)
您登陆的页面是反抓取页面,其构建目的是防止自动系统登录该页面。这意味着两个想法:
- 已检测到您的假冒浏览器(即使您是从传统 IP 连接)
- 他们试图阻止您。
这可以让您了解,在此过程中可能还有其他这种技术会阻止您继续,但值得一试。
首先,您可能只是由于 HTTP header 设置不当而被检测到,请尝试更改 BrowserVersion,甚至尝试重现真实浏览器的 HTTP header 。
如果它不起作用,我们很容易转到这里,如 form
也不是 input
包裹在 <noscript>
中标签(这里我告诉你 SURFspot 如何改进),这样你就可以解析表单 method
和action
属性和输入 name
和value
那么你只需要生成一个假的发布请求作为下一步(所以你不是点击按钮,而是假装如果你能够......
因此,生成一个表单帖子,其中包含正确的值到正确的 URL。检查他们是否为您设置了 cookie(如果是,也复制它们)并将正确的值设置为 realm
标题(他们也可能正在检查)并且门应打开。