web-dev-qa-db-fra.com

Comment extraire le nom de domaine de premier niveau (TLD) de l'URL

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

Ma tentative simpliste initiale était:

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

Cela fonctionne pour http://www.foo.com , mais pas http://www.foo.com.a . Existe-t-il un moyen de le faire correctement sans utiliser de connaissances particulières sur les TLD (domaines de premier niveau) ou les codes de pays valides (car ils changent).

merci

49
hoju

Non, il n'y a aucun moyen "intrinsèque" de savoir que (par exemple) zap.co.it est un sous-domaine (car le bureau d'enregistrement italien vend des domaines tels que co.it) tandis que zap.co.ukn'est pas (car le bureau d'enregistrement britannique NE VEND PAS de domaines tels que co.uk, mais seulement comme zap.co.uk).

Vous n'aurez qu'à utiliser une table auxiliaire (ou une source en ligne) pour vous dire quels TLD se comportent particulièrement comme ceux du Royaume-Uni et de l'Australie - il n'y a aucun moyen de deviner cela en regardant simplement la chaîne sans une telle connaissance sémantique supplémentaire (bien sûr, cela peut changer éventuellement, mais si vous pouvez trouver une bonne source en ligne, cette source changera également en conséquence, on espère! -).

43
Alex Martelli

Voici un excellent module python que 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 Public Suffix List , maintenue par les bénévoles de Mozilla

Citation:

tldextract d'autre part sait ce que tous les gTLD [ domaines génériques de premier niveau ] et ccTLD [ Les domaines de premier niveau de code de pays ] ressemblent en recherchant ceux actuellement en vigueur selon la Liste des suffixes publics . Ainsi, étant donné une URL, il connaît son sous-domaine à partir de son domaine et son domaine à partir de son code pays.

47
Acorn

Utiliser ce fichier de tlds efficaces qui quelqu'un d'autre trouvé sur le site Web 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ésulte en:

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 sur le last_i_elements liste, mais je n'y ai pas pensé. Je ne sais pas non plus si ValueError est la meilleure chose à faire. Commentaires?

42
Markus

Utilisation de python tld

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

Installer

pip install tld

Obtenez le nom du TLD sous forme de chaîne à partir de l'URL indiqué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

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

Obtenez le nom de domaine de premier niveau sous forme de chaîne à partir de l'URL indiquée

from tld import get_fld

get_fld("http://www.google.co.uk")
# 'google.co.uk'
26
Artur Barseghyan
2
S.Lott

Jusqu'à ce que get_tld soit mis à jour pour tous les nouveaux, je tire le tld de l'erreur. Bien sûr, c'est un mauvais code, mais cela fonctionne.

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
Russ Savage

Voici comment je le gère:

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
Ryan Buckley