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

StackOverflow https://stackoverflow.com/questions/1066933

Вопрос

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

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

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

Это работает для http://www.foo.com, но нет http://www.foo.com.au.Есть ли способ сделать это правильно, не используя специальные знания о действующих TLD (доменах верхнего уровня) или кодах стран (поскольку они меняются).

Спасибо

Это было полезно?

Решение

Нет, не существует «внутреннего» способа узнать это (например) zap.co.it является субдоменом (поскольку регистратор Италии ДЕЙСТВИТЕЛЬНО продает такие домены, как co.it) пока zap.co.uk не (поскольку регистратор Великобритании НЕ продает такие домены, как co.uk, но только как zap.co.uk).

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

Другие советы

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

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

Цитировать:

tldextract с другой стороны, знает, что все gTLD [Общие домены верхнего уровня] и cctlds [Домены верхнего уровня с кодом страны] Посмотрите, посмотрев, посмотрев в настоящее время живых в соответствии с Общественный список суффиксов.Таким образом, учитывая URL, он знает свой поддомен из своего домена и свой домен из кода страны.

С использованием этот файл эффективных доменов верхнего уровня который кто-нибудь другой нашел на сайте 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 это лучшее, что можно поднять.Комментарии?

Использование питона tld

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

Установить

pip install tld

Получите имя TLD в виде строки по указанному URL-адресу.

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

Ко. Великобритания

или без протокола

from tld import get_tld

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

Ко. Великобритания

Получите TLD как объект

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

Получите доменное имя первого уровня в виде строки по указанному URL-адресу.

from tld import get_fld

get_fld("http://www.google.co.uk")
# 'google.co.uk'

Существует много, много TLD.Вот список:

http://data.iana.org/TLD/tlds-alpha-by-domain.txt

Вот еще список

http://en.wikipedia.org/wiki/List_of_Internet_top-level_domains

Вот еще список

http://www.iana.org/domains/root/db/

Вот как я с этим справляюсь:

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)

Пока get_tld не обновится на все новые, выдергиваю 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

В Python я использовал tldextract пока это не дало сбой с URL-адресом типа www.mybrand.sa.com анализируя это как subdomain='order.mybrand', domain='sa', suffix='com'!!

Итак, наконец, я решил написать этот метод

ВАЖНАЯ ЗАМЕТКА:это работает только с URL-адресами, в которых есть субдомен.Это не предназначено для замены более продвинутых библиотек, таких как tldextract

def urlextract(url):
  url_split=url.split(".")
  if len(url_split) <= 2:
      raise Exception("Full url required with subdomain:",url)
  return {'subdomain': url_split[0], 'domain': url_split[1], 'suffix': ".".join(url_split[2:])}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top