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
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!-).
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.
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?
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'
il y a beaucoup, beaucoup de TLD. Voici la liste:
http://data.iana.org/TLD/tlds-alpha-by-domain.txt
voici une autre liste
http://en.wikipedia.org/wiki/List_of_Internet_top-level_domains
voici une autre liste
, 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)
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