Comment extraire un nom de domaine de premier niveau (TLD) de L'URL

comment extraire le nom de domaine d'une URL, à l'exclusion de tout sous-domaine?

ma première tentative simpliste a été:

'.'.join(urlparse.urlparse(url).netloc.split('.')[-2:])

ça marche pour http://www.foo.com , mais pas http://www.foo.com.au . Y a-t-il un moyen de le faire correctement sans utiliser de connaissances particulières sur les TLD valides (domaines de premier niveau) ou les codes de pays (parce qu'ils changent)?

merci

42
demandé sur John Carter 2009-07-01 05:42:03

7 réponses

Non, il n'y a aucun moyen" intrinsèque "de savoir que (par exemple) zap.co.it est un sous-domaine (parce que le registraire de L'Italie Vend des domaines tels que co.it ) tandis que zap.co.uk n'est pas (parce que le registraire du Royaume-Uni ne vend pas de domaines tels que co.uk , mais seulement comme zap.co.uk ).

vous aurez juste à utiliser une table auxiliaire (ou source en ligne) pour vous dire quel TLD se comportent particulièrement comme ROYAUME-UNI et L'Australie -- il n'y a aucun moyen de deviner cela en regardant simplement la corde sans une telle connaissance sémantique supplémentaire (bien sûr, il peut changer éventuellement, mais si vous pouvez trouver une bonne source en ligne que la source va également changer en conséquence, on espère!-).

42
répondu Alex Martelli 2009-07-01 01:48:50

voici un grand module python quelqu'un a écrit pour résoudre ce problème après avoir vu cette question: https://github.com/john-kurkowski/tldextract

le module Recherche Les TLD dans la liste de suffixe publique , gérée par Mozilla volunteers

citation:

tldextract d'un autre côté sait ce que tous les gTLD [ domaines génériques de premier niveau ] et ccTLD [ Country Code Top-Level Domains ] ressemblent à en regardant vers le haut de ceux qui vivent actuellement selon le le suffixe Public Liste . Ainsi, avec une URL, il connaît son sous-domaine à partir de son domaine, et son domaine de son code de pays.

40
répondu Acorn 2014-12-01 11:02:21

utilisant ce fichier de TLD effectifs que quelqu'un d'autre trouvé sur le site de 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)

résultats dans:

abcde.co.uk

j'apprécierais que quelqu'un me fasse savoir quels morceaux de ce qui précède pourraient être réécrits d'une manière plus pythonique. Par exemple, il doit y avoir une meilleure façon d'itérer au-dessus de la liste last_i_elements , mais je ne pouvais pas penser à un. Je ne sais pas non plus si ValueError est la meilleure chose à élever. Des commentaires?

40
répondu Markus 2017-05-23 12:10:30

utilisant python tld

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

Installer

pip install tld

Obtenir le nom de TLD comme une chaîne de caractères à partir de l'URL donnée

from tld import get_tld
print get_tld("http://www.google.co.uk") 

co.uk

ou sans protocole

from tld import get_tld

get_tld("www.google.co.uk", fix_protocol=True)

co.uk

Obtenir le TLD comme un objet

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=''
# )

obtenir le nom de domaine de premier niveau comme chaîne de l'URL donnée

from tld import get_fld

get_fld("http://www.google.co.uk")
# 'google.co.uk'
20
répondu Artur Barseghyan 2018-06-14 11:58:23
2
répondu S.Lott 2009-07-01 10:49:11

, Voici la façon dont je le manipuler:

if not url.startswith('http'):
    url = 'http://'+url
website = urlparse.urlparse(url)[1]
domain = ('.').join(website.split('.')[-2:])
match = re.search(r'((www\.)?([A-Z0-9.-]+\.[A-Z]{2,4}))', domain, re.I)
if not match:
    sys.exit(2)
elif not match.group(0):
    sys.exit(2)
0
répondu Ryan Buckley 2013-03-19 18:53:47

Jusqu'à ce que get_tld soit mis à jour pour tous les nouveaux, je tire le tld de l'erreur. C'est un mauvais code, mais ça marche.

def get_tld():
  try:
    return get_tld(self.content_url)
  except Exception, e:
    re_domain = re.compile("Domain ([^ ]+) didn't match any existing TLD name!");
    matchObj = re_domain.findall(str(e))
    if matchObj:
      for m in matchObj:
        return m
    raise e
0
répondu Russ Savage 2015-04-08 21:36:29