您将如何从 URL 中提取域名,不包括任何子域?
我最初的简单尝试是:
'.'.join(urlparse.urlparse(url).netloc.split('.')[-2:])
这适用于http://www.foo.com,但不适用于http://www.foo.com.au。有没有办法在不使用有关有效 TLD(顶级域)或国家代码(因为它们会更改)的特殊知识的情况下正确执行此操作。
谢谢
您将如何从 URL 中提取域名,不包括任何子域?
我最初的简单尝试是:
'.'.join(urlparse.urlparse(url).netloc.split('.')[-2:])
这适用于http://www.foo.com,但不适用于http://www.foo.com.au。有没有办法在不使用有关有效 TLD(顶级域)或国家代码(因为它们会更改)的特殊知识的情况下正确执行此操作。
谢谢
这是一个很棒的python模块,有人在看到这个问题后写来解决这个问题: https ://github.com/john-kurkowski/tldextract
该模块在由 Mozilla 志愿者维护的公共后缀列表中查找 TLD
引用:
tldextract
另一方面,通过根据公共后缀列表查找当前存在的gTLD [通用顶级域] 和 ccTLD [国家代码顶级域],了解所有 gTLD [通用顶级域] 和 ccTLD 的外观。因此,给定一个 URL,它从它的域知道它的子域,从它的国家代码知道它的域。
不,没有“内在”的方式可以知道(例如)zap.co.it
是子域(因为意大利的注册商确实销售诸如 的域co.it
)而zap.co.uk
不是(因为英国的注册商不销售诸如 的域co.uk
,而只销售诸如 的域zap.co.uk
)。
您只需要使用辅助表(或在线资源)来告诉您哪些 TLD 的行为与英国和澳大利亚的行为特别相似——如果没有额外的语义知识,仅盯着字符串是无法预测的(当然它可以最终会改变,但如果你能找到一个好的在线资源,该资源也会相应地改变,希望!-)。
使用其他人在 Mozilla 网站上找到的有效 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
是最好的提高。注释?
使用蟒蛇tld
https://pypi.python.org/pypi/tld
pip install tld
from tld import get_tld
print get_tld("http://www.google.co.uk")
联合英国
或无协议
from tld import get_tld
get_tld("www.google.co.uk", fix_protocol=True)
联合英国
from tld import get_tld
res = get_tld("http://some.subdomain.google.co.uk", as_object=True)
res
# 'co.uk'
res.subdomain
# 'some.subdomain'
res.domain
# 'google'
res.tld
# 'co.uk'
res.fld
# 'google.co.uk'
res.parsed_url
# SplitResult(
# scheme='http',
# netloc='some.subdomain.google.co.uk',
# path='',
# query='',
# fragment=''
# )
from tld import get_fld
get_fld("http://www.google.co.uk")
# 'google.co.uk'
有很多很多的顶级域名。这是列表:
http://data.iana.org/TLD/tlds-alpha-by-domain.txt
这是另一个列表
http://en.wikipedia.org/wiki/List_of_Internet_top-level_domains
这是另一个列表
在所有新的 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
这是我的处理方式:
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.-]+\.[A-Z]{2,4}))', domain, re.I)
if not match:
sys.exit(2)
elif not match.group(0):
sys.exit(2)
在 Python 中,我曾经使用tldextract直到它失败并出现一个 url,比如www.mybrand.sa.com
将其解析为subdomain='order.mybrand', domain='sa', suffix='com'
!!
所以最后,我决定写这个方法
重要提示:这仅适用于其中包含子域的 url。这并不是要替换更高级的库,例如tldextract
def urlextract(url):
url_split=url.split(".")
if len(url_split) <= 2:
raise Exception("Full url required with subdomain:",url)
return {'subdomain': url_split[0], 'domain': url_split[1], 'suffix': ".".join(url_split[2:])}