如何从URL中提取顶级域名(TLD)

你将如何从URL中提取域名,排除任何子域名?

我最初的简单尝试是:

'.'.join(urlparse.urlparse(url).netloc.split('.')[-2:]) 

这适用于http://www.foo.com ,但不适用于http://www.foo.com.au 。 是否有办法在不使用关于有效顶级域名(TLD)或国家/地区代码(因为它们发生变化)的特殊知识的情况下正确执行此操作。

谢谢

不,没有“内在”的方式知道(例如) zap.co.it是一个子域名(因为意大利的注册商DOES出售域名如co.it ),而zap.co.uk 不是 (因为英国的注册商不卖域名,如co.uk ,但只有像zap.co.uk )。

你只需要使用一个辅助表格(或在线资源)来告诉你哪个顶级域名(TLD)的行为特别像英国和澳大利亚那样 – 没有办法把它从只是盯着没有这种额外的语义知识的string中排除最终改变,但如果你能find一个好的在线来源,源也将相应改变,人们希望!)

使用其他人在Mozilla网站上find的这个有效tld文件 :

 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 

如果有人让我知道上面的哪些部分可以用更为pythonic的方式来重写,我将不胜感激。 例如,迭代last_i_elements列表必须有更好的方法,但是我想不出来。 我也不知道ValueError是否是最好的提升。 注释?

看到这个问题后,有人写了一个很好的python模块来解决这个问题: https : //github.com/john-kurkowski/tldextract

该模块在公共后缀列表中查找顶级域名,由Mozilla志愿者填写

引用:

另一方面,通过根据公共后缀列表查找当前tldextract的域名, tldextract知道所有的通用顶级域名(gTLD)和国家代码顶级域名(ccTLD)是什么样子的。 所以,给定一个URL,它就知道它的域的子域,以及它的国家代码的域。

使用python tld

https://pypi.python.org/pypi/tld

$ pip安装tld

 from tld import get_tld print get_tld("http://www.google.co.uk") 

google.co.uk

或没有协议:

 from tld import get_tld get_tld("www.google.co.uk", fix_protocol=True) 

google.co.uk

以下是我如何处理它:

 if not url.startswith('http'): url = 'http://'+url website = urlparse.urlparse(url)[1] domain = ('.').join(website.split('.')[-2:]) match = re.search(r'((www\.)?([A-Z0-9.-]+\.[AZ]{2,4}))', domain, re.I) if not match: sys.exit(2) elif not match.group(0): sys.exit(2) 

在get_tld更新所有新的之前,我从错误中提取tld。 当然这是错误的代码,但它的工作原理。

 def get_tld(): try: return get_tld(self.content_url) except Exception, e: re_domain = re.compile("Domain ([^ ]+) didn't match any existing TLD name!"); matchObj = re_domain.findall(str(e)) if matchObj: for m in matchObj: return m raise e