【问题标题】:Get Root Domain of Link获取链接的根域
【发布时间】:2010-12-04 01:02:07
【问题描述】:

我有一个链接,例如 http://www.techcrunch.com/,我想只获取链接的 techcrunch.com 部分。我如何在 python 中解决这个问题?

【问题讨论】:

标签: python regex dns root


【解决方案1】:

使用urlparse 获取主机名非常简单:

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

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

处理此问题的一种方法是使用Public Suffix List,它尝试对真正的顶级域(例如“.com”、“.net”、“.org”)以及私有域进行编目使用,例如 TLD(例如“.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)

【讨论】:

  • 请您解释一下这段代码 hostname = ".".join(len(hostname[-2])
  • @Joozty — 负索引从末尾开始,因此 hostname[-2] 表示倒数第二个条目(在这种情况下,主机名由点分隔)。 foo and bar or baz 工作起来很像三元:如果 "foo" 为真,则返回 "bar";否则,返回“baz”。最后,hostname[-3:] 表示最后三个部分。总而言之,这意味着“如果主机名的倒数第二部分短于四个字符,则使用最后三个部分并用点将它们连接在一起。否则,只取最后两个部分并将它们连接在一起。”
  • 出于某种原因,即使在安装模块之后,在 Python 3 上我也会收到 ImportError: cannot import name 'get_public_suffix'。在网上或文档中找不到任何答案,所以只使用“tldextract”代替它就可以了!当然,我必须先sudo pip3 install tldextract
【解决方案2】:

网址的一般结构:

scheme://netloc/path;parameters?query#fragment

作为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,它从它的域中知道它的子域,并且它的 来自其国家/地区代码的域。

欢呼! :)

【讨论】:

    【解决方案3】:

    以下脚本并不完美,但可用于显示/缩短目的。如果您真的想要/需要避免任何第 3 方依赖项 - 特别是远程获取和缓存一些 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
    

    【讨论】:

      【解决方案4】:

      ______使用 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 是一个顶级域名,而在http://sub.twitter.com 我们只有.com 作为顶级域名,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:])
      

      【讨论】:

        【解决方案5】:
        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:])
        

        【讨论】:

          【解决方案6】:

          你不需要一个包,也不需要人们建议这样做的任何复杂性,它就像下面一样简单,并根据你的喜好进行调整。

          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/')
          

          【讨论】:

            【解决方案7】:

            这对我有用:

            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
            

            【讨论】:

              【解决方案8】:

              这个简单的代码将从所有有效的 URL 中获取根域名。

              from urllib.parse import urlparse
              
              url = 'https://www.google.com/search?q=python'
              root_url = urlparse(url).scheme + '://' + urlparse(url).hostname
              print(root_url) # https://www.google.com
              

              【讨论】:

              • 这也解析三级域。 (www.)
              • 我更新了代码。现在检查。
              【解决方案9】:

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

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

              【讨论】:

              • 测试“www.sun.google.co.uk”怎么样?您将获得“co.uk”而不是“google.co.uk”...干杯!
              • 是的,使用 Ben Blank 的方法。不知道我在想什么(2010 年):-)
              猜你喜欢
              • 1970-01-01
              • 2016-01-18
              • 1970-01-01
              • 1970-01-01
              • 2011-07-19
              • 2019-04-24
              • 1970-01-01
              • 1970-01-01
              • 2012-05-12
              相关资源
              最近更新 更多