【问题标题】:implementing Public Suffix extraction using java使用java实现公共后缀提取
【发布时间】:2011-01-27 17:33:43
【问题描述】:

我需要提取一个 url 的顶级域,我得到了他的http://publicsuffix.org/index.html

Java 实现在http://guava-libraries.googlecode.com 中,我找不到 任何提取域名的例子

say example..
example.google.com
returns google.com

and bing.bing.bing.com
returns bing.com

谁能告诉我如何通过示例使用这个库来实现......

【问题讨论】:

  • 那么,您希望从 URL 中提取 TLD.com 部分)和 SLDgooglebing 部分)?
  • 如果您只想要域的最后两个部分,难道您不能只用String.split('\\.') 获取这些部分并返回最后两个部分吗?或者在(轻松)计算出适当的索引之后执行String.substring(indexOfPenultimatePeriod)?这里的复杂性是什么?
  • @Andrzej Doyle ya..你是对的,这是一个包含 10k 个具有不同后缀的 url 的 url 列表,例如 .com、.com.jp、.org、com.in 等。 ..
  • @ramuvan - 好点,您应该将这些案例添加到示例中。解决这个问题的唯一方法是拥有一个明确的 TLD 列表,并将您的域字符串的结尾与它们匹配。
  • @ramuvan:番石榴确实有一个解决方案可以让这一切变得简单......看我的回答。

标签: java guava domain-name tld


【解决方案1】:

在我看来,InternetDomainName.topPrivateDomain() 确实完全满足了你的要求。 Guava 维护一个公共后缀列表(基于 Mozilla 在 publicsuffix.org 上的列表),它用于确定主机的公共后缀部分是什么……顶级私有域是公共后缀加上它的第一个子域。

这是一个简单的例子:

public class Test {
  public static void main(String[] args) throws URISyntaxException {
    ImmutableList<String> urls = ImmutableList.of(
        "http://example.google.com", "http://google.com", 
        "http://bing.bing.bing.com", "http://www.amazon.co.jp/");
    for (String url : urls) {
      System.out.println(url + " -> " + getTopPrivateDomain(url));
    }
  }

  private static String getTopPrivateDomain(String url) throws URISyntaxException {
    String host = new URI(url).getHost();
    InternetDomainName domainName = InternetDomainName.from(host);
    return domainName.topPrivateDomain().name();
  }
}

运行此代码打印:

http://example.google.com -> google.com
http://google.com -> google.com
http://bing.bing.bing.com -> bing.com
http://www.amazon.co.jp/ -> amazon.co.jp

【讨论】:

  • TLD 和公共后缀不一样。例如http://myblog.blogspot.com -&gt; myblog.blogspot.com。阅读this了解更多详情
  • 你知道s3.amazonaws.com为什么返回null吗?
  • @Liquid: s3.amazonaws.com 本身就是一个公共后缀:publicsuffix.org/list/effective_tld_names.dat
  • 对不起,我工作得很好......我以错误的方式实现它。
  • [javac] symbol : method name() [javac] location: class com.google.common.net.InternetDomainName [javac] this.domain = domainName.topPrivateDomain().name(); [javac] ^ [javac] Note: Some input files use unchecked or unsafe operations. [javac] Note: Recompile with -Xlint:unchecked for details. [javac] 1 error 这个错误是什么意思?为什么是.name() 方法??
【解决方案2】:

我最近实现了一个Public Suffix List API

PublicSuffixList suffixList = new PublicSuffixListFactory().build();

assertEquals(
    "google.com", suffixList.getRegistrableDomain("example.google.com"));

assertEquals(
    "bing.com", suffixList.getRegistrableDomain("bing.bing.bing.com"));

assertEquals(
    "amazon.co.jp", suffixList.getRegistrableDomain("www.amazon.co.jp"));

【讨论】:

  • 你知道s3.amazonaws.com为什么返回null吗?
  • PSLs3.amazonaws.com 视为公共后缀。
【解决方案3】:

编辑:对不起,我有点太快了。我没有想到 co.jp。 co.uk 等等。您需要从某个地方获取可能的 TLD 列表。您还可以查看 http://commons.apache.org/validator/ 来验证 TLD。

我认为这样的事情应该可行:但也许存在一些 Java 标准函数。

String url = "http://www.foobar.com/someFolder/index.html";
if (url.contains("://")) {
  url = url.split("://")[1];
}

if (url.contains("/")) {
  url = url.split("/")[0];
}

// You need to get your TLDs from somewhere...
List<String> magicListofTLD = getTLDsFromSomewhere();

int positionOfTLD = -1;
String usedTLD = null;
for (String tld : magicListofTLD) {
  positionOfTLD = url.indexOf(tld);
  if (positionOfTLD > 0) {
    usedTLD = tld;
    break;
  }
}

if (positionOfTLD > 0) {
  url = url.substring(0, positionOfTLD);
} else {
  return;
}
String[] strings = url.split("\\.");

String foo = strings[strings.length - 1] + "." + usedTLD;
System.out.println(foo);

【讨论】:

  • 是的,抱歉,没有想到 co.jp、co.uk 等。我想您必须获取可能的 TLD 列表并尝试将它们与字符串匹配。
  • Guava 内置了执行此操作的功能,包括一个内部 TLD 列表,随着 TLD 列表的变化,该列表将随着新版本的更新而更新。最重要的是,Java 内置了解析和获取 URL 的主机部分的功能......我不认为使用 split 手动解析它是一个好主意。
  • @ColinD:不错的图书馆。不知道。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-10-13
  • 2018-11-17
  • 2011-08-01
  • 1970-01-01
相关资源
最近更新 更多