Python urlparse -- 提取不含子域名的域名

57 投票
7 回答
42699 浏览
提问于 2025-04-17 13:15

我需要一种方法,使用Python的urlparse从网址中提取不带子域名的域名。

举个例子,我想从完整的网址"http://www.google.com"中提取出"google.com"

我用urlparse得到的最接近的结果是netloc属性,但这个结果包含了子域名,在这个例子中就是www.google.com

我知道可以通过一些自定义的字符串处理把www.google.com变成google.com,但我想避免手动处理字符串或使用正则表达式。这样做的原因是我对网址的构成规则不够熟悉,不太有信心能考虑到所有特殊情况来写一个自定义的解析函数。

或者,如果urlparse无法满足我的需求,有没有人知道其他的Python网址解析库可以做到这一点?

7 个回答

9

这不是对网址的标准拆分方式。

你不能指望网址里一定会有或可以没有 www.。在很多情况下,它可能根本就没有。

所以,如果你想假设只有最后两个部分是重要的(这在英国的情况也不适用,比如 www.google.co.uk),你可以用 split('.')[-2:] 来处理。

或者,其实更不容易出错的方法是去掉 www. 的前缀。

但无论哪种方式,你都不能假设 www. 是可选的,因为这并不是每次都有效!

这里有一些常见的域名后缀。你可以尝试保留后缀加上一个部分。

https://mxr.mozilla.org/mozilla-central/source/netwerk/dns/effective_tld_names.dat?raw=1

但是你打算怎么处理像 first.last.name 这样的域名呢?假设所有同姓的用户都是同一家公司?最开始,你只能获取到三级域名。现在,看来你也可以获取到二级域名。所以对于 .name 来说,并没有通用的规则。

24

这是一个更新,基于对更新答案的悬赏请求。

首先,使用tld这个包。这个包的功能是:

从给定的URL中提取顶级域名(TLD)。TLD的名称列表来自Mozilla,具体链接是http://mxr.mozilla.org/mozilla/source/netwerk/dns/src/effective_tld_names.dat?raw=1

from tld import get_tld
from tld.utils import update_tld_names
update_tld_names()

print get_tld("http://www.google.co.uk")
print get_tld("http://zap.co.it")
print get_tld("http://google.com")
print get_tld("http://mail.google.com")
print get_tld("http://mail.google.co.uk")
print get_tld("http://google.co.uk")

这段代码的输出结果是:

google.co.uk
zap.co.it
google.com
google.com
google.co.uk
google.co.uk

注意,它能正确处理国家级的顶级域名,比如保留co.ukco.it,但会正确去掉wwwmail这两个子域名,适用于.com.co.uk

脚本开头的update_tld_names()调用是用来更新或同步最新的TLD名称,确保它们与Mozilla的最新版本一致。

79

你可能想看看tldextract这个库,它是专门用来处理这类事情的。

这个库使用了公共后缀列表,试图根据已知的通用顶级域名(gTLDs)来进行合理的拆分。不过要注意,这只是一个简单的列表,没有什么特别之处,所以可能会过时(不过希望它是经过整理的,不会太旧)。

>>> import tldextract
>>> tldextract.extract('http://forums.news.cnn.com/')
ExtractResult(subdomain='forums.news', domain='cnn', suffix='com')

所以在你的情况下:

>>> extracted = tldextract.extract('http://www.google.com')
>>> "{}.{}".format(extracted.domain, extracted.suffix)
"google.com"

撰写回答