获取链接的根域

时间:2009-10-05 18:16:13

标签: python regex dns root

我有http://www.techcrunch.com/之类的链接,我想获得该链接的techcrunch.com部分。我如何在python中进行此操作?

9 个答案:

答案 0 :(得分:25)

使用urlparse获取主机名很简单:

hostname = urlparse.urlparse("http://www.techcrunch.com/").hostname

然而,获得“根域”会更成问题,因为它没有在语法意义上定义。什么是“www.theregister.co.uk”的根域?网络使用默认域名怎么样? “devbox12”可以是有效的主机名。

处理此问题的一种方法是使用Public Suffix List,它会尝试对真正的顶级域名(例如“.com”,“。net”,“。org”)以及私有域进行编目使用 (例如“.co.uk”或甚至“.github.io”)。您可以使用publicsuffix2库从Python访问PSL:

import publicsuffix
import urlparse

def get_base_domain(url):
    # This causes an HTTP request; if your script is running more than,
    # say, once a day, you'd want to cache it yourself.  Make sure you
    # update frequently, though!
    psl = publicsuffix.fetch()

    hostname = urlparse.urlparse(url).hostname

    return publicsuffix.get_public_suffix(hostname, psl)

答案 1 :(得分:8)

网址的一般结构:

  

方案:// netloc /路径;参数查询#片段

作为 TIMTOWTDI 座右铭:

使用urlparse

>>> from urllib.parse import urlparse  # python 3.x
>>> parsed_uri = urlparse('http://www.stackoverflow.com/questions/41899120/whatever')  # returns six components
>>> domain = '{uri.netloc}/'.format(uri=parsed_uri)
>>> result = domain.replace('www.', '')  # as per your case
>>> print(result)
'stackoverflow.com/'  

使用tldextract

>>> import tldextract  # The module looks up TLDs in the Public Suffix List, mantained by Mozilla volunteers
>>> tldextract.extract('http://forums.news.cnn.com/')
ExtractResult(subdomain='forums.news', domain='cnn', suffix='com')

在你的情况下:

>>> extracted = tldextract.extract('http://www.techcrunch.com/')
>>> '{}.{}'.format(extracted.domain, extracted.suffix)
'techcrunch.com'
  另一方面,

tldextract知道所有gTLD [通用顶级域名]   和ccTLD [国家和地区代码顶级域名]看起来像   根据公共后缀查找当前生活的人   名单。因此,给定一个URL,它知道其域中的子域及其域   来自其国家/地区代码的域名。

Cheerio!的:)

答案 2 :(得分:2)

以下脚本并不完美,但可用于显示/缩短目的。如果你真的想要/需要避免任何第三方依赖 - 特别是远程获取和缓存一些tld数据,我可以建议你遵循我在我的项目中使用的脚本。对于大多数常见的域扩展,它使用域的最后两部分,并为其余不太知名的域扩展留下最后三部分。在最坏的情况下,场景将有三个部分而不是两个部分:

from urlparse import urlparse

def extract_domain(url):
    parsed_domain = urlparse(url)
    domain = parsed_domain.netloc or parsed_domain.path # Just in case, for urls without scheme
    domain_parts = domain.split('.')
    if len(domain_parts) > 2:
        return '.'.join(domain_parts[-(2 if domain_parts[-1] in {
            'com', 'net', 'org', 'io', 'ly', 'me', 'sh', 'fm', 'us'} else 3):])
    return domain

extract_domain('google.com')          # google.com
extract_domain('www.google.com')      # google.com
extract_domain('sub.sub2.google.com') # google.com
extract_domain('google.co.uk')        # google.co.uk
extract_domain('sub.google.co.uk')    # google.co.uk
extract_domain('www.google.com')      # google.com
extract_domain('sub.sub2.voila.fr')   # sub2.voila.fr

答案 3 :(得分:0)

______使用Python 3.3而不是2.x ________

我想在Ben Blank的答案中添加一些小东西。

from urllib.parse import quote,unquote,urlparse
u=unquote(u) #u= URL e.g. http://twitter.co.uk/hello/there
g=urlparse(u)
u=g.netloc

到目前为止,我刚从urlparse获得了域名。

要删除子域,首先您需要知道哪些是顶级域,哪些不是。例如。在上面http://twitter.co.uk - co.uk中是TLD,而http://sub.twitter.com我们只有.com作为TLD而sub是子域名。

因此,我们需要获得一个包含所有tlds的文件/列表。

tlds = load_file("tlds.txt") #tlds holds the list of tlds

hostname = u.split(".")
if len(hostname)>2:
    if hostname[-2].upper() in tlds:
        hostname=".".join(hostname[-3:])
    else:
        hostname=".".join(hostname[-2:])
else:
    hostname=".".join(hostname[-2:])

答案 4 :(得分:0)

def get_domain(url):
    u = urlsplit(url)
    return u.netloc

def get_top_domain(url):
    u"""
    >>> get_top_domain('http://www.google.com')
    'google.com'
    >>> get_top_domain('http://www.sina.com.cn')
    'sina.com.cn'
    >>> get_top_domain('http://bbc.co.uk')
    'bbc.co.uk'
    >>> get_top_domain('http://mail.cs.buaa.edu.cn')
    'buaa.edu.cn'
    """
    domain = get_domain(url)
    domain_parts = domain.split('.')
    if len(domain_parts) < 2:
        return domain
    top_domain_parts = 2
    # if a domain's last part is 2 letter long, it must be country name
    if len(domain_parts[-1]) == 2:
        if domain_parts[-1] in ['uk', 'jp']:
            if domain_parts[-2] in ['co', 'ac', 'me', 'gov', 'org', 'net']:
                top_domain_parts = 3
        else:
            if domain_parts[-2] in ['com', 'org', 'net', 'edu', 'gov']:
                top_domain_parts = 3
    return '.'.join(domain_parts[-top_domain_parts:])

答案 5 :(得分:0)

您不需要包装,或者人们建议这样做的任何复杂性,它如下所示,并且可以根据您的喜好进行调整。

def is_root(url):
    head, sep, tail = url.partition('//')
    is_root_domain = tail.split('/', 1)[0] if '/' in tail else url
    # printing or returning is_root_domain will give you what you seek
    print(is_root_domain)

is_root('http://www.techcrunch.com/')

答案 6 :(得分:0)

这对我有用:

def get_sub_domains(url):
    urlp = parseurl(url)
    urlsplit = urlp.netloc.split(".")
    l = []
    if len(urlsplit) < 3: return l
    for item in urlsplit:
        urlsplit = urlsplit[1:]
        l.append(".".join(urlsplit))
        if len(urlsplit) < 3:
            return l

答案 7 :(得分:0)

使用这种简单的拆分方法,我们几乎可以得到任何域名。

url = 'https://www.google.com'
if '//' in url:
    root_domain = url.split('//')[1].split('/')[0]
    print(root_domain) # 'www.google.com'
else:
    root_domain = url.split('/')[0]
    print(root_domain) # 'www.google.com'

答案 8 :(得分:-4)

这符合我的目的。我想我会分享它。

".".join("www.sun.google.com".split(".")[-2:])