1

我正在尝试从此页面检索链接:http ://www.seas.harvard.edu/academics/areas

页面中间有一个名为“计算机科学”的链接。其基础链接为“/academics/areas/computer-science”。我可以使用 Java 内置 URL 类将其转换为绝对 URL,获得“ http://www.seas.harvard.edu/academics/areas/computer-science ”。

但是,当我在 Chrome 浏览器中单击该链接时,绝对 URL 变为“ http://www.seas.harvard.edu/computer-science ”。

所以我的问题有两个:

  1. URL 重定向如何在此页面中工作?
  2. Java中是否有任何库或方法可以帮助我在重定向后获取URL?

我需要在重定向后获取 URL,因为我想读取页面的源代码,但重定向前的 URL 对我不起作用。我正在使用该JSoup库从 URL 中读取,所以我怀疑它可能是基于 javascript 的重定向。

4

5 回答 5

4

curl --dump-header [file] [URL]文件看起来像:

HTTP/1.1 301 Moved Permanently
Age: 0
Cache-Control: no-cache, must-revalidate, post-check=0, pre-check=0
Content-Type: text/html
Date: Tue, 13 Aug 2013 13:00:12 GMT
ETag: "1376398812"
Expires: Sun, 19 Nov 1978 05:00:00 GMT
Last-Modified: Tue, 13 Aug 2013 13:00:12 GMT
Location: http://www.seas.harvard.edu/computer-science
Server: nginx
Vary: Accept-Encoding
Via: 1.1 varnish
X-AH-Environment: prod
X-Cache: MISS
X-Drupal-Cache: MISS
X-Redirect-ID: 44
X-Varnish: 2704315535
transfer-encoding: chunked
Connection: keep-alive

如您所见,这是从服务器提供的 301 永久重定向。

要获取数据:

您可以使用 HttpURLConnection 进行连接,但在连接之前,请调用myConn.setInstanceFollowRedirects(true). 遵循重定向,您可以获取输出流并读取它。

要获取 URL 本身:

您可以使用HttpURLConnection连接,但在连接之前,调用myConn.setInstanceFollowRedirects(false)遵循重定向。这会将实际的 URL 保存在正确的位置。

这里的诀窍是,出于某种奇怪的原因,除非您将其解析为日期,否则HttpURLConnection 不允许按名称检索标头。

因此,您将需要迭代一个整数,getHeaderFieldKey在建立连接后调用并检查它是否等于Location,如果是,则getHeaderField使用相同的整数来获取位置。烦人,我知道。但是位置不是日期,这是 JRE 的疏忽。

于 2013-08-13T13:09:41.957 回答
0

我使用 Fiddler 进行调查,站点返回链接http://www.seas.harvard.edu/academics/areas/computer-science HTTP 301 响应代码,执行重定向。

我想获得真实的 URL。您应该对 harvard.edu Web 服务器执行真实请求并解析响应。(重定向 URL 位于LocationHTTP Header 中的键中)。

对不起你的第二个问题。我没有Java技能。

这个 SO 问题可能会有所帮助(httpclient-4-how-to-capture-last-redirect-url

于 2013-08-13T13:08:26.347 回答
0
  1. 可能有例如 a.htaccessmod_rewrite重定向。使用 Firefox 的控制台我可以看到请求。正如您在下面看到的,服务器正在发回一条301 Moved Permanently消息。Location这告诉浏览器重定向到响应标头中 返回的地址。网络请求
  2. 获取更改后的 URL 的方式取决于您加载页面的方式:
    • 如果您使用现成的库和代码将页面加载到例如 DOM 对象,您可以使用该现成的 HTTP 系统来加载响应,这可能会导致它自动重定向 -> 您将从加载的页面。如果它没有这样做,那么您必须检查状态代码 301 或 302,当收到这些状态代码时,更改后的 URL 位于Location响应的标头中。
    • 如果您编写了自己的代码来通过 TCP 套接字加载响应,那么您必须照常加载响应,但再次检查 301 和 302 状态代码并按照上一节中的说明进行操作。
于 2013-08-13T13:09:10.517 回答
0

因为我不是 Java 程序员,所以我只能尝试解决 Q1。源代码说他们正在使用 Drupal,所以我推测他们正在使用 Drupal 的全局重定向模块(关于 Drupal 重定向模块的讨论here)。查看模块的文档可能会对如何使用 Java 获取正确的 url 有所了解。

在 javascript 中还有很多方法可以让 url 请求自动重定向到某个基本页面(例如 CS 主页),同时物理导航站点允许用户前进到新页面。这是许多单页 Web 应用程序中的标准做法。如果是这种情况,那么 @hexafraction 的建议可能能够帮助您检索所需的 url,尽管我不熟悉他建议的 Java 方法。

于 2013-08-13T13:19:53.813 回答
0

您可以Redirect URL从以下代码设置followRedirects中获取false.

如果您将其设置为,您将获得重定向页面的源代码,true这是默认行为Jsoup

 Connection con = Jsoup.connect("http://www.seas.harvard.edu/academics/areas/computer-science")
                              .userAgent("Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.110 Safari/537.36")
                              .followRedirects(false);

           System.out.println("Redirected Url : " + con.execute().header("Location")); //null if followRedirect is true

           Document doc = con.get();
           System.out.println(doc.html());
           System.out.println("=================================================");
于 2013-08-13T22:22:46.753 回答