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

hoj*_*oju 49 python dns url parsing extract

如何从URL中提取域名,不包括任何子域名?

我最初的简单尝试是:

'.'.join(urlparse.urlparse(url).netloc.split('.')[-2:])
Run Code Online (Sandbox Code Playgroud)

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

谢谢

Aco*_*orn 48

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

该模块在公共后缀列表中查找TLD ,由Mozilla志愿者提供

引用:

tldextract另一方面,根据公共后缀列表查找当前生存的gTLD,通用顶级域名(通用顶级域名)和国家和地区代码顶级域名(国家地区代码顶级域名)是什么样的.因此,给定一个URL,它从其域中知道其子域,并从其国家代码中知道其域.

  • 在`tld`失败的情况下,这对我有用(它将有效的 URL 标记为无效)。 (2认同)
  • 花了太多时间思考这个问题,应该从一开始就知道并使用这一点。 (2认同)

Ale*_*lli 43

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

你只需要使用一个辅助表(或在线资源)来告诉你哪个TLD的行为特别像英国和澳大利亚 - 没有办法在没有这些额外语义知识的情况下仅仅盯着字符串(当然它可以最终会改变,但如果你能找到一个好的在线资源,那么资源也会相应改变,人们希望! - ).


Mar*_*kus 42

使用有效的TLD文件,其别人 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)
Run Code Online (Sandbox Code Playgroud)

结果是:

abcde.co.uk
Run Code Online (Sandbox Code Playgroud)

如果有人让我知道上面哪些部分可以用更加pythonic的方式重写,我会很感激.例如,必须有更好的迭代last_i_elements列表的方法,但我想不出一个.我也不知道是否ValueError是最好的事情.评论?

  • 如果你需要经常在实践中调用getDomain(),比如从大型日志文件中提取域名,我建议你将tlds设置为一个集合,例如tlds = set([line.strip()for line in tldFile if line [ 0]不在"/ \n"]中.这为您提供了每个检查的持续时间查找,以确定某个项目是否在tld中.我看到查找(设置与列表)的速度大约是1500次,并且我的整个操作从大约2000万行日志文件中提取域,大约是60倍的加速(从6小时开始下降6分钟). (10认同)

Art*_*yan 26

使用python tld

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

安装

pip install tld
Run Code Online (Sandbox Code Playgroud)

从给定的URL获取TLD名称作为字符串

from tld import get_tld
print get_tld("http://www.google.co.uk") 
Run Code Online (Sandbox Code Playgroud)

co.uk

或没有协议

from tld import get_tld

get_tld("www.google.co.uk", fix_protocol=True)
Run Code Online (Sandbox Code Playgroud)

co.uk

获取TLD作为对象

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=''
# )
Run Code Online (Sandbox Code Playgroud)

从给定的URL获取第一级域名作为字符串

from tld import get_fld

get_fld("http://www.google.co.uk")
# 'google.co.uk'
Run Code Online (Sandbox Code Playgroud)

  • 新通用顶级域名(gTLD)将变得更加不可靠. (2认同)
  • @Akshay Patil:如上所述,当谈到大量使用gTLD时,将在包装中提供适当的修复(如果可能的话)。同时,如果您非常关心gTLD,则始终可以捕获tld.exceptions.TldDomainNotFound异常,并继续执行您所做的任何操作,即使未找到域也是如此。 (2认同)