1

我目前正在使用 JTidy 解析 HTML 文档并获取给定 HTML 文档中所有锚标记的集合。然后,我提取每个标签的 href 属性的值,以在页面上生成一组链接。

不幸的是,这些链接可以用几种不同的方式表示:一些绝对的(http://www.example.com/page.html),一些相​​对的(/page.htmlpage.html../page.html)。甚至,有些可能只是锚(#paragraphA)。当我在浏览器中访问我的页面时,如果我要单击链接,它会自动知道如何处理这些不同的 href 值,但是如果我要使用 HTTPClient 以编程方式跟踪从 JTidy 检索到的这些链接之一,我首先需要提供一个有效的 URL(例如,我首先需要将 /page.html、page.html 和http://www.example.com/page.html转换为http://www.example.com/page.html) .

是否有一些内置功能,无论是在 JTidy 还是其他地方,都可以为我实现这一点?还是我需要创建自己的规则来将这些不同的 URL 转换为绝对 URL?

4

2 回答 2

3

假设您可以确定要使用的上下文,vanilla URL 类可能会帮助您完成大部分工作。这里有些例子:

package grimbo.url;

import java.net.MalformedURLException;
import java.net.URL;

public class TestURL {
    public static void main(String[] args) {
        // context1
        URL c1 = u(null, "http://www.example.com/page.html");
        u(c1, "http://www.example.com/page.html");
        u(c1, "/page.html");
        u(c1, "page.html");
        u(c1, "../page.html");
        u(c1, "#paragraphA");

        System.out.println();

        // context2
        URL c2 = u(null, "http://www.example.com/path/to/page.html");
        u(c2, "http://www.example.com/page.html");
        u(c2, "/page.html");
        u(c2, "page.html");
        u(c2, "../page.html");
        u(c2, "#paragraphA");
    }

    public static URL u(URL context, String url) {
        try {
            URL u = null != context ? new URL(context, url) : new URL(url);
            System.out.println(u);
            return u;
        } catch (MalformedURLException e) {
            e.printStackTrace();
            return null;
        }
    }
}

结果是:

http://www.example.com/page.html
http://www.example.com/page.html
http://www.example.com/page.html
http://www.example.com/page.html
http://www.example.com/../page.html
http://www.example.com/page.html#paragraphA

http://www.example.com/path/to/page.html
http://www.example.com/page.html
http://www.example.com/page.html
http://www.example.com/path/to/page.html
http://www.example.com/path/page.html
http://www.example.com/path/to/page.html#paragraphA

如您所见,有些结果不是您想要的。因此,也许您尝试new URL(value)先使用解析 URL,如果结果是 a,MalformedURLException您可以尝试相对于上下文 URL。

于 2011-12-20T00:16:06.943 回答
1

如HTML 规范中所述,您最好的方法最有可能遵循与浏览器相同的解析过程:

用户代理必须根据以下优先级(从最高优先级到最低优先级)计算基本 URI:

  1. 基本 URI 由 BASE 元素设置。
  2. 基本 URI 由在协议交互期间发现的元数据给出,例如 HTTP 标头(参见 [RFC2616])。
  3. 默认情况下,基本 URI 是当前文档的基本 URI。并非所有的 HTML 文档都有一个基本的 URI(例如,一个有效的 HTML 文档可能出现在电子邮件中,并且可能不是由 URI 指定的)。如果此类 HTML 文档包含相对 URI 并依赖于默认的基本 URI,则认为它们是错误的。

在实践中,您可能最关心数字 1 和 2(即检查 a<base href="..."并使用它(如果存在)或当前文档的 URI)。

于 2011-12-19T23:57:43.670 回答