Получение субдомена по URL-адресу поначалу кажется простым.
http://www.domain.example
Просканируйте первый период, затем верните все, что было после "http: //" ...
Тогда ты помнишь
http://super.duper.domain.example
Ой. Тогда вы думаете, хорошо, найдите последний период, вернитесь на слово назад и получите все, что было раньше!
Тогда ты помнишь
http://super.duper.domain.co.uk
И вы вернулись на круги своя. У кого-нибудь есть отличные идеи, кроме хранения списка всех TLD?
Ответы:
Нет, потому что каждый TLD отличается тем, что считается субдоменом, доменом второго уровня и т. Д.
Имейте в виду, что существуют домены верхнего уровня, домены второго уровня и субдомены. Технически говоря, все, кроме TLD, является субдоменом.
В примере domain.com.uk «domain» - это поддомен, «com» - это домен второго уровня, а «uk» - это TLD.
Таким образом, вопрос остается более сложным, чем на первый взгляд, и зависит от того, как осуществляется управление каждым TLD. Вам понадобится база данных всех TLD, которые включают их конкретное разделение и то, что считается доменом второго уровня и субдоменом. Однако TLD не так уж и много, поэтому список достаточно управляем, но собрать всю эту информацию нетривиально. Возможно, такой список уже есть.
Похоже, что http://publicsuffix.org/ является одним из таких списков - все общие суффиксы (.com, .co.uk и т. Д.) В списке, подходящем для поиска. Разобрать его по-прежнему будет непросто, но, по крайней мере, вам не нужно поддерживать список.
Просматривая список , вы понимаете, что это нетривиальная проблема. Я думаю, что список - единственный правильный способ добиться этого ...
источник
http://publicsuffix.org
, я опубликовал некоторые функции оболочки и bash на основе вашего ответа: stackoverflow.com/a/63761712/1765658Как говорит Адам, это непросто, и в настоящее время единственный практический способ - использовать список.
Даже в этом случае есть исключения - например,
.uk
есть несколько доменов, которые действительны сразу на этом уровне, но не в них.co.uk
, поэтому их нужно добавлять в качестве исключений.В настоящее время это делают основные браузеры - необходимо убедиться, что
example.co.uk
нельзя установить файл cookie,.co.uk
который затем будет отправлен на любой другой веб-сайт.co.uk
.Хорошей новостью является то, что список уже доступен на http://publicsuffix.org/ .
В IETF также идет работа по созданию некоего стандарта, позволяющего TLD объявлять, как выглядит их доменная структура. Это немного усложняется тем
.uk.com
, что работает, как если бы это был общедоступный суффикс, но не продается в.com
реестре.источник
.uk
реестр доменов теперь разрешает регистрацию непосредственно на втором уровне. Это соответственно отражено в PSL.Publicsuffix.org кажется подходящим вариантом. Существует множество реализаций, позволяющих легко анализировать содержимое файла данных publicsuffix:
источник
Как уже сказали Адам и Джон, publicsuffix.org - это правильный путь. Но, если по какой-либо причине вы не можете использовать этот подход, вот эвристика, основанная на предположении, которое работает для 99% всех доменов:
Есть одно свойство, которое отличает (не все, но почти все) «настоящие» домены от поддоменов и TLD, и это запись MX DNS. Вы можете создать алгоритм, который будет искать это: одну за другой удалять части имени хоста и запрашивать DNS, пока не найдете запись MX. Пример:
Вот пример на php:
источник
.ai
или.ax
просто назовите несколько).Как уже было сказано, список общедоступных суффиксов - это только один способ правильно проанализировать домен. Для PHP вы можете попробовать TLDExtract . Вот пример кода:
источник
Просто написал для этого программу в clojure на основе информации с publicsuffix.org:
https://github.com/isaksky/url_dom
Например:
источник
Для библиотеки C (с генерацией таблиц данных в Python) я написал http://code.google.com/p/domain-registry-provider/, который работает быстро и эффективно.
Библиотека использует ~ 30 КБ для таблиц данных и ~ 10 КБ для кода C. Нет дополнительных затрат на запуск, поскольку таблицы создаются во время компиляции. См. Http://code.google.com/p/domain-registry-provider/wiki/DesignDoc для получения дополнительных сведений.
Чтобы лучше понять код генерации таблиц (Python), начните здесь: http://code.google.com/p/domain-registry-provider/source/browse/trunk/src/registry_tables_generator/registry_tables_generator.py
Чтобы лучше понять C API, см. Http://code.google.com/p/domain-registry-provider/source/browse/trunk/src/domain_registry/domain_registry.h
источник
оболочка и трепать версии
В дополнение к правильному ответу Адама Дэвиса я хотел бы опубликовать свое собственное решение для этой операции.
Поскольку список довольно большой, есть три из множества различных протестированных решений ...
Сначала подготовьте свой список TLD таким образом:
Примечание:
tac
перевернет список, чтобы гарантировать тестирование.co.uk
перед.uk
.Posix версия оболочки
Тесты:
трепать версия
Чтобы уменьшить количество вилок (избегая
myvar=$(function..)
синтаксиса), я предпочитаю устанавливать переменные вместо вывода вывода на стандартный вывод в функциях bash:Затем:
Быстрее трепать версия:
С такой же подготовкой:
Этот шаг значительно медленнее, но
splitDom
функция станет намного быстрее:Тесты на моем raspberry-pi:
Обе трепать скрипты были протестированы с:
Posixверсия была протестирована с подробным
for
циклом, ноВсе тестовые скрипты производят одинаковый результат:
Полный скрипт, содержащий чтение файла и
splitDom
цикл, занимает ~ 2 м с версией posix, ~ 1 мин 29 с с первым скриптом bash на основе$tlds
массива, но~22s
с последним скриптом bash на основе$TLDS
ассоциативного массива .Так что, если заполнение ассоциативного массива - более сложная задача,
splitDom
функция станет намного быстрее!источник
Это не совсем так, но вы могли бы получить полезный ответ, пытаясь получить домен по частям и проверяя ответ, то есть получить ' http: // uk ', затем ' http://co.uk ' , затем " http://domain.co.uk ". Когда вы получаете ответ без ошибки, у вас есть домен, а остальное - поддомен.
Иногда нужно просто попробовать :)
Редактировать:
Том Лейс указывает в комментариях, что некоторые домены настроены только на субдомене www, что даст нам неправильный ответ в приведенном выше тесте. Хорошая точка зрения! Может быть, лучшим подходом было бы проверить каждую часть с помощью ' http: // www ', а также 'http: //' и засчитать попадание в любой из них как попадание для этого раздела доменного имени? Нам все равно не хватало бы некоторых «альтернативных» договоренностей, таких как «web.domain.com», но я давно не встречал ни одного из них :)
источник
.DK
и на некоторых других, так какhttp://dk/
работает как есть. Этот вид эвристики не подходит ...Используйте URIBuilder, затем получите атрибут URIBUilder.host, разделив его на массив на "." теперь у вас есть массив с разделенным доменом.
источник
источник
Вы можете использовать эту библиотеку tld.js: JavaScript API для работы со сложными доменными именами, поддоменами и URI.
Если вы получаете корневой домен в браузере. Вы можете использовать эту библиотеку AngusFu / browser-root-domain .
Использовать cookie сложно.
источник
Если вы хотите извлечь поддомены и / или домены из произвольного списка URL-адресов, этот скрипт python может оказаться полезным. Но будьте осторожны, это не идеально. Это сложная проблема для решения в целом, и она очень полезна, если у вас есть белый список ожидаемых доменов.
источник
Список общих суффиксов (.co.uk, .com и т. Д.), Которые нужно исключить вместе с http: //, и тогда у вас будет только «sub.domain» для работы вместо « http: // sub. domain.suffix ", или, по крайней мере, я бы так сделал.
Самая большая проблема - это список возможных суффиксов. В конце концов, их много.
источник
Бегло взглянув на список publicsuffix.org, кажется, что вы могли бы сделать разумное приближение, удалив последние три сегмента («сегмент» здесь означает раздел между двумя точками) из доменов, где последний сегмент состоит из двух символов, при условии, что это код страны, который будет делиться дальше. Если последний сегмент - это «нас», а предпоследний сегмент также состоит из двух символов, удалите последние четыре сегмента. Во всех остальных случаях удалите последние два сегмента. например:
"example" - это не два символа, поэтому удалите "domain.example", оставив "www".
"example" - это не два символа, поэтому удалите "domain.example", оставив "super.duper"
"uk" - это два символа (но не "us"), поэтому удалите "domain.co.uk", оставив "super.duper"
«us» - это два символа, это «us», плюс «wy» - это также два символа, поэтому удалите «pvt.k12.wy.us», оставив «foo».
Обратите внимание, что, хотя это работает для всех примеров, которые я видел в ответах, это остается лишь разумным приближением. Это не совсем правильно, хотя я подозреваю, что это настолько близко, насколько вы могли бы получить без создания / получения фактического списка для использования в качестве справки.
источник
.NAME
, когда вы могли покупать толькоfirstname.lastname.name
доменные имена. И в обратном направлении, сейчас.US
также плоско, так что вы можетеx.y.z.whatever.us
просто купитьwhatever.us
в реестре, и тогда ваш алгоритм не сработает.