0

我有以下代码行从给定的 URL 收集源代码:

URL url = new URL(websiteAddress);
URLConnection connection = url.openConnection();  // throws an IOException
connection.setConnectTimeout(timeoutInMilliseconds);
bufferedReader = new BufferedReader(new InputStreamReader(connection.getInputStream()));

String line;
while ((line = bufferedReader.readLine()) != null) {
    outputString += line;
}

但是,我遇到的问题是 Wi-Fi 热点通常会将您重定向到您必须单击“我同意”的页面。如果您在单击该复选框之前运行此代码,那么它会从热点登录页面而不是预期页面收集源代码。

我想要做的是有一些方法来检查是否到达了预期的页面。我希望connection.getURL()在创建 InputStreamReader 后调用会显示到达的实际网页,但没有这样的运气。如何确定预期的 URL 是否已被重定向?

4

3 回答 3

1

一种方法是在您的web页面中查找任何特定元素,如果它不存在,那么您知道您可能在其他页面中(可能重定向到某个登录页面)。

于 2013-09-10T21:34:21.443 回答
0

一种选择是调用setFollowRedirects(false). 默认情况下,连接会悄悄地跟随重定向并尝试到达返回200HTTP 响应的页面。禁用重定向跟踪将使确认返回的预期页面更容易,只需确认响应是200.

也就是说,@rec 的评论值得考虑 - 仅仅检查响应代码是不够的,因为路由器可以通过多种不同的方式中断您的请求,其中许多是无法检测到的。例如,恶意路由器可以拦截您的所有请求并以一种微妙但危险的方式更改响应内容 - 这称为中间人攻击

根据定义,除非您可以在自己和远程站点之间打开安全且受信任的连接(通常是 HTTPS),否则您无法避免中间人攻击,但是假设您并不真正关心攻击,更好的策略是简单地假设您获得的数据back 可以通过多种方式被破坏,而是使您的抓取逻辑对这种可能性更加健壮。

在不了解您的用例和遇到的问题的情况下,我无法直接谈论如何使您的逻辑更加健壮,但要点是在可能出现问题的地方添加检查,然后抛出一个异常,然后处理优雅地在堆栈中更高。

例如,如果您的代码是:

System.out.println(outputString.subString(outputString.indexOf('A'));

如果outputString didn't actually have an'A'` 字符,这将失败。因此,请明确检查:

int aPos = outputString.indexOf('A');
if (aPos < 0) {
  throw new InvalidParseException("Didn't find an 'A', cannot proceed");
}
System.out.println(outputString.subString(aPos);

并处理InvalidParseException对您的用例最有意义的地方。

于 2014-01-06T08:40:48.980 回答
0

我唯一能建议的是有一个服务器,你知道响应是什么,并首先查询它以确保至少连接到该服务器。这将(通常)足以假设完全连接。

然后您可以继续查询您感兴趣的网址。

挑战在于,如果计算机在某个 url 处请求页面,许多 wifi 热点的工作方式是拦截该请求并返回页面。通常没有线索,从计算机的 POV 中返回的页面不是请求的页面。

于 2013-09-10T22:19:25.927 回答