如何从URL中提取顶级域名(TLD)
你想从一个网址中提取出主域名,但不包括任何子域名,该怎么做呢?
我最开始的简单尝试是:
'.'.join(urlparse.urlparse(url).netloc.split('.')[-2:])
这个方法对 http://www.foo.com 有用,但对 http://www.foo.com.au 就不行了。
有没有什么好的方法可以做到这一点,而不需要特别了解有效的顶级域名(TLD)或国家代码(因为这些会变化)呢?
谢谢!
8 个回答
使用这个有效的顶级域名文件,这是其他人在Mozilla网站上找到的:
from __future__ import with_statement
from urlparse import urlparse
# load tlds, ignore comments and empty lines:
with open("effective_tld_names.dat.txt") as tld_file:
tlds = [line.strip() for line in tld_file if line[0] not in "/\n"]
def get_domain(url, tlds):
url_elements = urlparse(url)[1].split('.')
# url_elements = ["abcde","co","uk"]
for i in range(-len(url_elements), 0):
last_i_elements = url_elements[i:]
# i=-3: ["abcde","co","uk"]
# i=-2: ["co","uk"]
# i=-1: ["uk"] etc
candidate = ".".join(last_i_elements) # abcde.co.uk, co.uk, uk
wildcard_candidate = ".".join(["*"] + last_i_elements[1:]) # *.co.uk, *.uk, *
exception_candidate = "!" + candidate
# match tlds:
if (exception_candidate in tlds):
return ".".join(url_elements[i:])
if (candidate in tlds or wildcard_candidate in tlds):
return ".".join(url_elements[i-1:])
# returns "abcde.co.uk"
raise ValueError("Domain not in global list of TLDs")
print get_domain("http://abcde.co.uk", tlds)
结果是:
abcde.co.uk
如果有人能告诉我上面的哪些部分可以用更符合Python风格的方式重写,我会很感激。例如,遍历last_i_elements
列表肯定有更好的方法,但我想不出来。我也不知道ValueError
是否是最合适的错误类型。有什么意见吗?
这里有一个很棒的Python模块,是有人在看到这个问题后写出来的,用来解决这个问题:https://github.com/john-kurkowski/tldextract
这个模块会查找公共后缀列表中的顶级域名,这个列表是由Mozilla的志愿者维护的,大家可以在这里找到。
引用:
这个
tldextract
模块能够识别所有的通用顶级域名(gTLDs)和国家代码顶级域名(ccTLDs),它通过查找当前存在的域名来实现这一点,这些信息都在公共后缀列表中。因此,给定一个网址,它可以从域名中识别出子域名,从国家代码中识别出域名。
不,实际上没有一种“内置”的方法可以知道,比如说 zap.co.it
是一个子域名(因为意大利的注册商确实出售像 co.it
这样的域名),而 zap.co.uk
不是(因为英国的注册商不出售像 co.uk
这样的域名,只出售像 zap.co.uk
这样的域名)。
你只能使用一个辅助表格(或者在线资源)来告诉你哪些顶级域名(TLD)像英国和澳大利亚那样表现得比较特殊——光靠看字符串是无法知道这些的,因为你需要额外的语义知识(当然,这些情况可能会改变,但如果你能找到一个好的在线资源,那些信息也会相应更新,希望如此!)。