使用Python从URL获取子域名

13

这个问题应该很有用:https://dev59.com/fHNA5IYBdhLWcg3wKai3 - Acorn
12个回答

27

使用tldextract包可以轻松完成这个任务,如果需要更多的信息,可以使用建议的urlparse:

>>> import tldextract
>>> tldextract.extract("http://lol1.domain.com:8888/some/page"
ExtractResult(subdomain='lol1', domain='domain', suffix='com')
>>> tldextract.extract("http://sub.lol1.domain.com:8888/some/page"
ExtractResult(subdomain='sub.lol1', domain='domain', suffix='com')
>>> urlparse.urlparse("http://sub.lol1.domain.com:8888/some/page")
ParseResult(scheme='http', netloc='sub.lol1.domain.com:8888', path='/some/page', params='', query='', fragment='')

请注意,tldextract 可以正确处理子域名。


这应该是答案。谢谢。 - John Z
很棒的答案,应该被投票选为最佳答案 :) 谢谢Lluis - Tom St

20

urlparse.urlparse会将URL拆分为协议、位置、端口等。然后您可以按.拆分位置以获取子域。

import urlparse
url = urlparse.urlparse(address)
subdomain = url.hostname.split('.')[0]

非常好用。我使用它的方式是 Node = urlparse.urlparse(address).hostname.split('.')[0]。 - Marko
5
如果它是一个IP地址呢?如果它有第二级子域名呢? - naktinis
2
子域名可能包含多个点,因此“api.test”也是有效的,请记住这一点。如果您想要一个好的程序包来执行此操作,请查看“https://pypi.python.org/pypi/tldextract”。 - sidneydobber
6
这个回答其实很不好。如果没有子域名会返回主域名而不是空值。对于 IP 地址来说无法处理(好吧,可以理解),还有多个子域名的情况也处理不了,比如 web.host1.google.com - mlissner
4
在Python 3.x中,您需要通过from urllib.parse import urlparse进行导入。 - Lord Elrond
显示剩余2条评论

5

以下是对这个精彩答案的修改版本:如何从URL中提取顶级域名(TLD)

您需要从这里获取有效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 tldFile:
    tlds = [line.strip() for line in tldFile if line[0] not in "/\n"]

class DomainParts(object):
    def __init__(self, domain_parts, tld):
        self.domain = None
        self.subdomains = None
        self.tld = tld
        if domain_parts:
            self.domain = domain_parts[-1]
            if len(domain_parts) > 1:
                self.subdomains = domain_parts[:-1]

def get_domain_parts(url, tlds):
    urlElements = urlparse(url).hostname.split('.')
    # urlElements = ["abcde","co","uk"]
    for i in range(-len(urlElements),0):
        lastIElements = urlElements[i:]
        #    i=-3: ["abcde","co","uk"]
        #    i=-2: ["co","uk"]
        #    i=-1: ["uk"] etc

        candidate = ".".join(lastIElements) # abcde.co.uk, co.uk, uk
        wildcardCandidate = ".".join(["*"]+lastIElements[1:]) # *.co.uk, *.uk, *
        exceptionCandidate = "!"+candidate

        # match tlds: 
        if (exceptionCandidate in tlds):
            return ".".join(urlElements[i:]) 
        if (candidate in tlds or wildcardCandidate in tlds):
            return DomainParts(urlElements[:i], '.'.join(urlElements[i:]))
            # returns ["abcde"]

    raise ValueError("Domain not in global list of TLDs")

domain_parts = get_domain_parts("http://sub2.sub1.example.co.uk:80",tlds)
print "Domain:", domain_parts.domain
print "Subdomains:", domain_parts.subdomains or "None"
print "TLD:", domain_parts.tld

给您:

域名: example
子域名: ['sub2', 'sub1']
顶级域名: co.uk

1
更新了“有效顶级域名列表”的链接:https://wiki.mozilla.org/Public_Suffix_List#TLD_Lists,http://publicsuffix.org/ - Rivers

4
一个非常基本的方法,没有任何检查,可能看起来像这样:
address = 'http://lol1.domain.com:8888/some/page'

host = address.partition('://')[2]
sub_addr = host.partition('.')[0]

print sub_addr

当您说“子域名”时,这当然是指主机名的第一部分,因此在以下情况下,“www”将成为子域名:http://www.google.com/。您是这个意思吗?

2
你所需要的在这里: http://docs.python.org/library/urlparse.html 例如: ".".join(urlparse('http://www.my.cwi.nl:80/%7Eguido/Python.html').netloc.split(".")[:-2]) 这将帮你完成任务(将返回“www.my”)。

2
这假设主域名有两个部分 - 在某些情况下会出现问题,例如 .co.uk 地址。除了英国外,以色列、巴西和日本都有正式的二级域名,可能还有其他国家也有。 - Thomas K
我的答案使用有效顶级域名列表来解决这个问题。 - Acorn

1

将所有域名标准化为以www.开头,除非它们有子域名。

from urllib.parse import urlparse
    
def has_subdomain(url):
    if len(url.split('.')) > 2:
        return True
    else:
        return False 

domain = urlparse(url).netloc
        
if not has_subdomain(url):
        domain_name = 'www.' + domain
        url = urlparse(url).scheme + '://' + domain

1
首先导入 tldextract,因为它将 URL 拆分为其组成部分,如: 子域名、域名和后缀
import tldextract

然后声明一个变量(比如ext),它用于存储查询的结果。我们还需要用双引号将URL放在括号中提供给它。如下所示:
ext = tldextract.extract("http://lol1.domain.com:8888/some/page")


如果我们尝试运行 ext 变量,输出将是:
ExtractResult(subdomain='lol1', domain='domain', suffix='com')

如果你只想使用子域名、域名或后缀,那么分别使用以下任意代码。
ext.subdomain

结果将会是:

'lol1'

ext.domain

结果将会是:

'domain'

ext.suffix

结果将会是:

'com'

另外,如果你想将子域名的结果仅存储在一个变量中,那么使用下面的代码:

Sub_Domain = ext.subdomain

然后打印子域名

Sub_Domain

结果将会是:

'lol1'

0

使用Python 3(我具体使用的是3.9版本),您可以执行以下操作:

from urllib.parse import urlparse

address = 'http://lol1.domain.com:8888/some/page'

url = urlparse(address)

url.hostname.split('.')[0]

0

要提取主机名,我会使用urllib2中的urlparse:

>>> from urllib2 import urlparse
>>> a = "http://lol1.domain.com:8888/some/page"
>>> urlparse.urlparse(a).hostname
'lol1.domain.com'

关于如何提取子域名,您需要考虑完整域名可能会更长的情况。如何操作将取决于您的目的。我建议剥离掉最右边的两个组件。
例如:
>>> urlparse.urlparse(a).hostname.rpartition('.')[0].rpartition('.')[0]
'lol1'

0

我们可以使用https://github.com/john-kurkowski/tldextract解决这个问题...

很简单。

>>> ext = tldextract.extract('http://forums.bbc.co.uk')
>>> (ext.subdomain, ext.domain, ext.suffix)
('forums', 'bbc', 'co.uk')

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接