Jak wyodrębnić nazwę domeny najwyższego poziomu (TLD) z adresu URL

Jak wyodrębnić nazwę domeny z adresu URL, z wyłączeniem subdomen?

Moja początkowa uproszczona próba brzmiała:

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

To działa dla http://www.foo.com , ale nie http://www.foo.com.au . Czy istnieje sposób, aby to zrobić poprawnie bez użycia specjalnej wiedzy na temat ważnych domen najwyższego poziomu (TLD) lub kodów krajów (ponieważ się zmieniają).

Thanks

Author: John Carter, 2009-07-01

7 answers

Nie, Nie ma "wewnętrznego" sposobu, aby wiedzieć ,że (np.) {[0] } jest subdomeną (ponieważ Włoski rejestrator sprzedaje domeny takie jak co.it), podczas gdy zap.co.uk nie jest (ponieważ rejestrator w Wielkiej Brytanii nie sprzedaje domen takich jak co.uk, a tylko jak zap.co.uk).

Będziesz musiał użyć tabeli pomocniczej (lub źródła online), aby powiedzieć, które TLD zachowują się dziwnie jak brytyjskie i Australijskie -- nie ma sposobu, aby wywnioskować, że po prostu patrząc na ciąg bez takiego dodatkowego semantycznego wiedza (oczywiście może się w końcu zmienić, ale jeśli uda Ci się znaleźć dobre źródło online, które również zmieni się odpowiednio, można mieć nadzieję!-).

 42
Author: Alex Martelli,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-07-01 01:48:50

Oto świetny moduł Pythona, który ktoś napisał, aby rozwiązać ten problem po obejrzeniu tego pytania: https://github.com/john-kurkowski/tldextract

Moduł wyszukuje domeny TLD na publicznej liście sufiksów , obsługiwanej przez wolontariuszy Mozilli

Cytat:

tldextract z drugiej strony wie, co wszystkie gTLD [ogólne domeny najwyższego poziomu ] i ccTLD [kod kraju domeny najwyższego poziomu] wyglądają następująco poszukując obecnie żyjących zgodnie z przyrostkiem Public Lista . Więc, biorąc pod uwagę adres URL, zna swoją subdomenę ze swojej domeny, a jej domena z kodu kraju.

 40
Author: Acorn,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-12-01 11:02:21

Używając tego pliku skutecznych TLD, który ktoś inny znalazł na stronie Mozilli:

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)

Wyniki w:

abcde.co.uk

Byłbym wdzięczny, gdyby ktoś dał mi znać, które fragmenty powyższego można przepisać w bardziej pythoniczny sposób. Na przykład, musi być lepszy sposób iteracji listy last_i_elements, ale nie mogłem wymyślić żadnej. Nie wiem też, czy to najlepsza rzecz do wychowania. Komentarze?

 40
Author: Markus,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:10:30

Using python tld

Https://pypi.python.org/pypi/tld

Zainstaluj

pip install tld

Pobierz nazwę TLD jako ciąg znaków z podanego adresu URL

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

Co.uk

Lub bez protokołu

from tld import get_tld

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

Co.uk

Pobierz TLD jako obiekt

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

Pobierz nazwę domeny pierwszego poziomu jako ciąg znaków z podanego adresu URL

from tld import get_fld

get_fld("http://www.google.co.uk")
# 'google.co.uk'
 20
Author: Artur Barseghyan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-14 11:58:23
 2
Author: S.Lott,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-07-01 10:49:11

Oto jak sobie z tym radzę:

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
Author: Ryan Buckley,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-03-19 18:53:47

Dopóki get_tld nie zostanie zaktualizowane dla wszystkich nowych, wyciągam tld z błędu. Pewnie, że to zły kod, ale działa.

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
Author: Russ Savage,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-04-08 21:36:29