Как извлечь доменное имя верхнего уровня (TLD) из URL

Как бы вы извлекли доменное имя из URL, за исключением каких-либо поддоменов?

Моя первоначальная упрощенная попытка была:

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

Это работает дляhttp://www.foo.com, но нетhttp://www.foo.com.au. Is there a way to do this properly without using special knowledge about valid TLDs (Top Level Domains) or country codes (because they change).

Спасибо

 Conspicuous Compiler01 июл. 2009 г., 03:48
Ранее связанный вопрос о переполнении стека:stackoverflow.com/questions/569137/…
 user231473701 дек. 2014 г., 12:04
Подобный вопрос:stackoverflow.com/questions/14406300/…
 ArtOfWarfare24 июн. 2014 г., 17:12
+1: «упрощенная попытка» этот вопрос хорошо работает для меня, даже если по иронии судьбы он не работает для автора.

Ответы на вопрос(7)

этот файл эффективных Tlds которыйкто-нибудь другой найдено на веб-сайте 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)

результаты в:

abcde.co.uk

Я был бы признателен, если бы кто-нибудь дал мне знать, какие биты из вышеперечисленного могут быть переписаны более питоническим способом. Например, должен быть лучший способ перебораlast_i_elements список, но я не мог думать об одном. Я также не знаю, еслиValueError лучше всего поднять. Комментарии?

 04 авг. 2015 г., 15:50
Это круто! Еще один вопрос: этоeffective_tld_names.dat файл также обновлен для новых доменов, таких как.amsterdam, .vodka а также.wtf?
 07 авг. 2010 г., 06:14
Если на практике вам нужно часто вызывать getDomain (), например, извлекать домены из большого файла журнала, я бы порекомендовал сделать tlds набором, например, tlds = set ([line.strip () для строки в tldFile, если строка [0] отсутствует в & quot; / \ n & quot;]). Это дает вам постоянный поиск по каждой из этих проверок на предмет наличия какого-либо элемента в tlds. Я видел ускорение примерно в 1500 раз для поиска (набор или список) и для всей моей операции извлечения доменов из файла журнала ~ 20 миллионов строк, примерно в 60 раз (6 минут по сравнению с 6 часами).
 29 мар. 2017 г., 12:35
Да, список общедоступных суффиксов Mozilla регулярно обновляется, и теперь у него есть несколько библиотек Python, которые его включают. Увидетьpublicsuffix.org и другие ответы на этой странице.

tld

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

Install
pip install tld
Get the TLD name as string from the URL given
from tld import get_tld
print get_tld("http://www.google.co.uk") 

co.uk

or without protocol

from tld import get_tld

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

co.uk

Get the TLD as an object
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=''
# )
Get the first level domain name as string from the URL given
from tld import get_fld

get_fld("http://www.google.co.uk")
# 'google.co.uk'
 26 июн. 2014 г., 15:40
Это станет более ненадежным с новыми gTLD.
 01 июл. 2009 г., 09:38
Это не помогает, потому что не говорит вам, какие из них имеют «дополнительный уровень», например co.uk.
 01 июл. 2009 г., 11:08
Леннарт: Это помогает, вы можете заключать их в необязательные выражения в регулярном выражении.
Решение Вопроса

zap.co.it является поддоменом (потому что регистратор Италии продает домены, такие какco.it) в то время какzap.co.uk isn't (потому что регистратор Великобритании НЕ продает домены, такие какco.uk, но только какzap.co.uk).

Вам просто нужно будет использовать вспомогательную таблицу (или онлайн-источник), чтобы сообщить вам, какие ДВУ ведут себя особенно по-британски и в Австралии - нет никакого способа отличить это от простого взгляда на строку без такого дополнительное семантическое знание (конечно, оно может измениться со временем, но если вы сможете найти хороший онлайн-источник, этот источник также изменится соответствующим образом, можно надеяться! -).

я извлекаю tld из ошибки. Конечно, это плохой код, но он работает.

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

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)
 18 апр. 2013 г., 02:18
Есть домен .travel. Он не будет работать с приведенным выше кодом.

который кто-то написал, чтобы решить эту проблему, увидев этот вопрос: https://github.com/john-kurkowski/tldextract

Модуль ищет TLD вПубличный список суффиксов, поддерживаемый волонтерами Mozilla

Цитата:

tldextract on the other hand knows what all gTLDs [Generic Top-Level Domains] and ccTLDs [Country Code Top-Level Domains] look like by looking up the currently living ones according to the Public Suffix List. So, given a URL, it knows its subdomain from its domain, and its domain from its country code.

 04 окт. 2016 г., 19:49
Это сработало для меня, гдеtld не удалось (он пометил действительный URL-адрес как недействительный).

Ваш ответ на вопрос