Получить поддомен из URL - PullRequest
       58

Получить поддомен из URL

100 голосов
/ 14 ноября 2008

Поначалу получение субдомена из URL звучит просто.

http://www.domain.example

Сканирование для первого периода, а затем возврат того, что было после "http://" ...

Тогда вы помните

http://super.duper.domain.example

О. Итак, вы думаете, хорошо, найдите последний период, вернитесь на слово и получите все раньше!

Тогда вы помните

http://super.duper.domain.co.uk

И вы вернулись на круги своя. У кого-нибудь есть отличные идеи, кроме хранения списка всех TLD?

Ответы [ 15 ]

71 голосов
/ 14 ноября 2008

У кого-нибудь есть отличные идеи, кроме хранить список всех TLD?

Нет, поскольку каждый TLD отличается от того, что считается субдоменом, доменом второго уровня и т. Д.

Имейте в виду, что существуют домены верхнего уровня, домены второго уровня и поддоменов. Технически говоря, все, кроме TLD, является поддоменом.

В примере domain.com.uk «домен» - это поддомен, «com» ​​- это домен второго уровня, а «uk» - это TLD.

Таким образом, вопрос остается более сложным, чем на первый взгляд, и зависит от того, как управляется каждый TLD. Вам понадобится база данных всех TLD, которые включают в себя их конкретное разделение и то, что считается доменом второго уровня и поддоменом. Однако TLD не слишком много, поэтому этот список достаточно управляем, но собрать всю эту информацию нетривиально. Возможно, такой список уже имеется.

Похоже, http://publicsuffix.org/ - это один из таких списков - все общие суффиксы (.com, .co.uk и т. Д.) В списке, подходящем для поиска. Разобрать его все равно будет непросто, но, по крайней мере, вам не нужно вести список.

«Публичный суффикс» - это тот, под которым Интернет-пользователи могут напрямую зарегистрироваться имена. Некоторые примеры публичного Суффиксами являются ".com", ".co.uk" и "Pvt.k12.wy.us". Общественный суффикс Список - это список всех известных публике суффиксы.

Публичный список суффиксов является инициатива фонда Mozilla. Доступно для использования в любом программное обеспечение, но изначально был создан для удовлетворения потребностей браузера производители. Это позволяет браузерам например:

  • Избегайте "супер-печенья", наносящего ущерб конфиденциальности суффиксы доменных имен высокого уровня
  • Выделите наиболее важную часть доменного имени у пользователя интерфейс
  • Точная сортировка записей истории по сайту

Просматривая список , вы видите, что это не тривиальная проблема. Я думаю, что список - единственный правильный способ сделать это ...

26 голосов
/ 14 ноября 2008

Как говорит Адам, это нелегко, и в настоящее время единственным практическим способом является использование списка.

Даже тогда есть исключения - например, в .uk есть несколько доменов, которые действительны немедленно на том уровне, которых нет в .co.uk, поэтому они должны быть добавлены как исключения.

Это в настоящее время так делают основные браузеры - необходимо убедиться, что example.co.uk не может установить Cookie для .co.uk, который затем будет отправлен на любой другой веб-сайт под .co.uk.

Хорошей новостью является то, что список уже доступен на http://publicsuffix.org/.

В IETF также есть некоторая работа по созданию какого-то стандарта, позволяющего доменам верхнего уровня декларировать, как выглядит их доменная структура. Это немного сложнее, например, из-за .uk.com, который работает, как если бы он был общедоступным суффиксом, но не продается реестром .com.

21 голосов
/ 07 июня 2009

Publicsuffix.org, кажется, способ сделать. Существует множество реализаций для простого анализа содержимого файла данных publicsuffix:

9 голосов
/ 04 февраля 2013

Как уже сказали Адам и Джон publicsuffix.org - правильный путь. Но если по какой-либо причине вы не можете использовать этот подход, вот эвристика, основанная на предположении, которое работает для 99% всех доменов:

Существует одно свойство, которое отличает (не все, но почти все) «реальные» домены от поддоменов и TLD, и это запись MX DNS. Вы можете создать алгоритм, который ищет это: удаляйте части имени хоста одну за другой и запрашивайте DNS, пока не найдете запись MX. Пример:

super.duper.domain.co.uk => no MX record, proceed
duper.domain.co.uk       => no MX record, proceed
domain.co.uk             => MX record found! assume that's the domain

Вот пример в php:

function getDomainWithMX($url) {
    //parse hostname from URL 
    //http://www.example.co.uk/index.php => www.example.co.uk
    $urlParts = parse_url($url);
    if ($urlParts === false || empty($urlParts["host"])) 
        throw new InvalidArgumentException("Malformed URL");

    //find first partial name with MX record
    $hostnameParts = explode(".", $urlParts["host"]);
    do {
        $hostname = implode(".", $hostnameParts);
        if (checkdnsrr($hostname, "MX")) return $hostname;
    } while (array_shift($hostnameParts) !== null);

    throw new DomainException("No MX record found");
}
2 голосов
/ 23 июня 2016

Как уже говорилось Public Suffix List - это только один способ правильно проанализировать домен. Для PHP вы можете попробовать TLDExtract . Вот пример кода:

$extract = new LayerShifter\TLDExtract\Extract();

$result = $extract->parse('super.duper.domain.co.uk');
$result->getSubdomain(); // will return (string) 'super.duper'
$result->getSubdomains(); // will return (array) ['super', 'duper']
$result->getHostname(); // will return (string) 'domain'
$result->getSuffix(); // will return (string) 'co.uk'
1 голос
/ 06 декабря 2012

Для библиотеки 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

Чтобы лучше понять API C, см .: http://code.google.com/p/domain-registry-provider/source/browse/trunk/src/domain_registry/domain_registry.h

1 голос
/ 20 марта 2012

Только что написал программу для этого в ближайшем будущем, основываясь на информации из publicsuffix.org:

https://github.com/isaksky/url_dom

Например:

(parse "sub1.sub2.domain.co.uk") 
;=> {:public-suffix "co.uk", :domain "domain.co.uk", :rule-used "*.uk"}
0 голосов
/ 29 ноября 2018

Если вы хотите извлечь субдомены и / или домены из произвольного списка URL-адресов, этот скрипт на python может быть полезен. Будьте осторожны, это не идеально. В общем, это сложная проблема, и она очень полезна, если у вас есть белый список ожидаемых доменов.

  1. Получить домены верхнего уровня от publicsuffix.org
import requests

url = 'https://publicsuffix.org/list/public_suffix_list.dat'
page = requests.get(url)

domains = []
for line in page.text.splitlines():
    if line.startswith('//'):
        continue
    else:
        domain = line.strip()
        if domain:
            domains.append(domain)

domains = [d[2:] if d.startswith('*.') else d for d in domains]
print('found {} domains'.format(len(domains)))
  1. Построить регулярное выражение
import re

_regex = ''
for domain in domains:
    _regex += r'{}|'.format(domain.replace('.', '\.'))

subdomain_regex = r'/([^/]*)\.[^/.]+\.({})/.*$'.format(_regex)
domain_regex = r'([^/.]+\.({}))/.*$'.format(_regex)
  1. Использовать регулярное выражение в списке URL
FILE_NAME = ''   # put CSV file name here
URL_COLNAME = '' # put URL column name here

import pandas as pd

df = pd.read_csv(FILE_NAME)
urls = df[URL_COLNAME].astype(str) + '/' # note: adding / as a hack to help regex

df['sub_domain_extracted'] = urls.str.extract(pat=subdomain_regex, expand=True)[0]
df['domain_extracted'] = urls.str.extract(pat=domain_regex, expand=True)[0]

df.to_csv('extracted_domains.csv', index=False)
0 голосов
/ 09 мая 2017

Вы можете использовать этот lib tld.js: JavaScript API для работы со сложными доменными именами, поддоменами и URI.

tldjs.getDomain('mail.google.co.uk');
// -> 'google.co.uk'

Если вы получаете корневой домен в браузере. Вы можете использовать эту lib AngusFu / browser-root-domain .

var KEY = '__rT_dM__' + (+new Date());
var R = new RegExp('(^|;)\\s*' + KEY + '=1');
var Y1970 = (new Date(0)).toUTCString();

module.exports = function getRootDomain() {
  var domain = document.domain || location.hostname;
  var list = domain.split('.');
  var len = list.length;
  var temp = '';
  var temp2 = '';

  while (len--) {
    temp = list.slice(len).join('.');
    temp2 = KEY + '=1;domain=.' + temp;

    // try to set cookie
    document.cookie = temp2;

    if (R.test(document.cookie)) {
      // clear
      document.cookie = temp2 + ';expires=' + Y1970;
      return temp;
    }
  }
};

Использовать cookie сложно.

0 голосов
/ 07 апреля 2014

Я только что написал библиотеку objc: https://github.com/kejinlu/KKDomain

...