Как извлечь доменное имя верхнего уровня (TLD) из URL-адреса
Вопрос
как бы вы извлекли имя домена из 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
Вот еще список
Вот как я с этим справляюсь:
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:])}