如何从URL的hostname中取出主域名

解决进度

移动到答案中去了

问题定义

先说一下【主域名】的定义,就是指一个人通过域名注册商注册的那个名字(domain name),它在注册商的系统中有个唯一的域名ID。

如t.sina.com.cn的主域名就是sina.com.cn,www.sf.gg的的主域名就是sf.gg

本来我想说根域名,但是怕大伙儿讨论的时候跟Root DNS的概念弄混了。

举例:

hostname             ->  主域名
sf.gg                ->  sf.gg
image.google.com.hk  ->  google.com.hk
www.example.com      ->  example.com
www.yahoo.co.jp      ->  yahoo.co.jp
www.online.sh.cn     ->  online.sh.cn
www.sh.cn            ->  sh.cn
www.nc.jx.cn         ->  nc.jx.cn
www.jx.cn            ->  www.jx.cn
deal.z.cn            ->  z.cn

我的努力

这无非是个字符串匹配的问题,我首先没去找现成的类库,从wikipedia上整理出了顶级国际域名的后缀(TLD,Top Level Domain,如com, org, net, gov)和国家域名(ccTLD,Country Code Top Level Domain,如cn, uk, hk, tw, jp)

但,我只发现TLD是能观察出规律的,都是3-4位,ccTLD是有ISO标准的,都是2位。

把hostname用点号分隔,从最后一段开始处理,是3-4位的是国际域名,连同倒数第二段返回即可。

如果最后一段是2位,那就是国家域名,返回最后一段、倒数第二段,很可能也需要倒数第三段。让我无法逾越的问题出现了:

无法确定倒数第三段是子域名,还是主域名的一部分

例如,yahoo.co.jp,co根本不是一个TLD。因为TLD都是3-4位,也意味着倒数第二段哪些是保留的(如根据CNNIC的规定,各省份的两位字母缩写就是保留不可公开注册的),是较难制作字典的。

即使倒数第二位是保留的,程序遇到www.jx.cn(中国机械网)和www.nc.jx.cn(江西南昌市官方网站)的时候也不能正确处理。

我查了ccTLD的维基资料,也没找到规范来帮我解决www.jx.cn和www.nc.jx.cn的问题。

试着搜索了英文资料,找到的资料大多是parse_url的,根据它们的源码判断,他们也解决不了我这个问题。

如果再找不到规范,我想,有一个笨办法:查whois信息。不从规范上理论判断,从现实存在的域名中判断。

我想得到的帮助

任何帮助和提示,我都很乐意看到。我特别想知道:

  • 域名国际标准中,有没有一个概念是和我所描述的主域名对应的?类似TLD、ccTLD这样的
  • www.jx.cn和www.nc.jx.cn在DNS里的查询路径是怎样的?
  • www.jx.cn(中国机械网)这种与保留ccTLD重名的,是不是不能再设置二级域名?如blog.jx.cn, bbs.jx.cn应该是不允许的吧,否则就与nc.jx.cn冲突了
阅读 25.7k
5 个回答

Mozilla 是专门有个列表的。Text link 扩展也自带了个列表。

另外,有少数几个顶层域名是可以直接访问的。

用 dig 命令可以知道 DNS 查询路径:

dig +trace www.nc.jx.cn

1 国际域名(TLD)

完美解决
最后一段是3-4位的是国际域名,倒数第一、第二段即为主域名

2 国家域名(ccTLD)

最后一段是2位的是国家域名

@依云 告知的列表(Mozilla整理)可判断最后的两段是否构成保留域名。

中国的保留域名列表可在CNNIC官方网站查到

2.1 非保留域名

完美解决
如10086.cn, t.cn, z.cn,方法与国际域名相同

2.2 保留域名

2.2.1 保留域名加上www作为一个主域名

--- 2013-12-20更新 ---
net.cn(中国万网)、edu.cn(中国教育科研网)、gov.cn(中国政府网)、jx.cn(中国机械网)、sh.cn(魔酷网),他们的域名是包含www的,也就是说,中国万网的域名实际是www.net.cn,如果它要设置子域名,子域名就像这样:bbs.www.net.cn。

证据:http://whois.chinaz.com/blog.www.jx.cn

从程序处理的角度,www.net.cn和sina.net.cn没有区别。

因此,2.2.1章节可以和下面的2.2.2章节合并。感谢@新一 指出错误。

--- 2013-12-20更新 ---

如,net.cn(中国万网)、edu.cn(中国教育科研网)、gov.cn(中国政府网)、jx.cn(中国机械网)、sh.cn(魔酷网)。

经过观察和抽样调查(样本空间大于10),这些域名本身当做一个网站的域名使用时,不可再使用三级域名,也就是说,没有blog.jx.cn, bbs.edu.cn这种子域名,如果你看到这样的“子域名”,他们实际上是一个独立的主域名了,在注册商的whois系统中拥有独立的域名ID。

举个例子:
中国政府网它的首页有繁体、英文版的链接,使用的是big5.gov.cn, english.gov.cn,看起来好像是中国政府网的子域名,网站内容和拥有者都是一致的,实际上,这是三个域名,他们的域名ID分别是:

20021209s10061s00001917-cn
20050830s10061s00638003-cn
20031217s10061s00023256-cn

我抽样调查的网站,全都符合这个规律,但是没有找到ICANN的官方规定证明这一点。

如果这个规律能成立,那就好办了,当hostname=gov.cn/www.gov.cn时,它的主域名就是gov.cn,其它保留域名亦同此理。

虽然没找到明文规定(中国机械网不得设置域名泛解析,不得设置除www.jx.cn以外的三级域名),但能从侧面推论:

假设允许jx.cn设置除www以外的三级域名,那等于是将整个jx.cn域下的子域名处置权都交给了中国机械网的拥有者,江西省内的地级市、学校、企业和事业单位想申请一个xxx.jx.cn的域名都要经由中国机械网的审批,或者避免与中国机械网既有的三级域名重复,这显然是不可能的。

2.2.2 保留域名下属的主域名

完美解决

如sina.com.cn(新浪网)、people.com.cn(人民网)、hust.edu.cn(华中科技大学)、online.sh.cn(上海热线)

倒数第一、第二、第三段共同构成一个主域名

PHP代码实现(含单元测试):

https://github.com/qinjx/lotusphp/tree/master/runtime/DomainName

感谢楼主的详尽分析。
PSL项目下给出了各个编程语言的第三方库:
各个库的地址可从下方链接中找出:
https://publicsuffix.org/learn/