如何从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
有许多顶级域名。 列表如下:
http://data.iana.org/TLD/tlds-alpha-by-domain.txt
这是另一个列表
http://en.wikipedia.org/wiki/List_of_Internet_top-level_domains
这是另一个列表
以下是我如何处理它:
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