Obtener el subdominio de una URL


Obtener el subdominio de una URL suena fácil al principio.

http://www.domain.example

Escanee el primer período y luego devuelva lo que vino después del "http://" ...

Entonces te acuerdas

http://super.duper.domain.example

Oh. Entonces piensas, bien, encontrar el último período, volver una palabra y obtener todo antes!

Entonces te acuerdas

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

Y vuelves al punto de partida. ¿Alguien tiene grandes ideas además de almacenar una lista de todos los TLDs?

Author: Ry-, 2008-11-14

14 answers

Cualquiera tiene grandes ideas además almacenando una lista de todos los TLDs?

No, porque cada TLD difiere en lo que cuenta como subdominio, dominio de segundo nivel, etc.

Tenga en cuenta que hay dominios de nivel superior, dominios de segundo nivel y subdominios. Técnicamente hablando, todo excepto el TLD es un subdominio.

En el domain.com.uk por ejemplo, domain es un subdominio, com es un dominio de segundo nivel y uk es el tld.

Así que la pregunta sigue siendo más complejo que a primera vista, y depende de cómo se gestione cada TLD. Necesitará una base de datos de todos los TLDs que incluyen su partición particular, y lo que cuenta como un dominio de segundo nivel y un subdominio. Sin embargo, no hay demasiados TLDs, por lo que la lista es razonablemente manejable, pero recopilar toda esa información no es trivial. Es posible que ya haya una lista de este tipo disponible.

Parece http://publicsuffix.org / es una de esas listas-todos los sufijos comunes (. com, .co.uk, etc.) en una lista adecuada para la búsqueda. Todavía no será fácil analizarlo, pero al menos no tienes que mantener la lista.

Un "sufijo público" es uno bajo el cual Los usuarios de Internet pueden registrarse directamente nombre. Algunos ejemplos de público los sufijos son". com",". co.uk " y "pvt.k12.wy.us". El Sufijo Público Lista es una lista de todos los públicos conocidos sufijos.

La Lista Pública de Sufijos es una iniciativa de la Fundación Mozilla. Está disponible para su uso en cualquier software, pero fue creado originalmente para satisfacer las necesidades del navegador fabricante. Permite a los navegadores, por ejemplo:

  • Evite que se establezcan "supercookies" perjudiciales para la privacidad sufijos de nombres de dominio de alto nivel
  • Resalte la parte más importante de un nombre de dominio en el usuario interfaz
  • Ordenar con precisión las entradas del historial por sitio

Mirando a través de la lista , se puede ver que no es un problema trivial. Creo que un la lista es la única manera correcta de lograr esto...

-Adam

 67
Author: Adam Davis,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-03-24 07:30:13

Como dice Adam, no es fácil, y actualmente la única manera práctica es usar una lista.

Incluso entonces hay excepciones - por ejemplo en .uk hay un puñado de dominios que son válidos inmediatamente en ese nivel que no están en .co.uk, por lo que deben agregarse como excepciones.

Esta es la actualidad de cómo los navegadores más populares ello, es necesario asegurarse de que example.co.uk no se puede establecer una Cookie para .co.uk, que luego sería enviado a cualquier otro sitio web bajo .co.uk.

El bien noticia es que ya hay una lista disponible en http://publicsuffix.org/.

También hay algo de trabajo en el IETF para crear algún tipo de estándar que permita a los TLDs declarar cómo se ve su estructura de dominio. Esto es un poco complicado, aunque por los gustos de .uk.com, que se opera como si fuera un sufijo público, pero no se vende por el registro .com.

 25
Author: Alnitak,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-10-01 14:55:13

Publicsuffix.org parece la forma de hacerlo. Hay un montón de implementaciones por ahí para analizar el contenido del archivo de datos publicsuffix fácilmente:

 21
Author: JohnTESlade,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-02-12 14:20:57

Como ya dijeron Adán y Juan publicsuffix.org es el camino correcto a seguir. Pero, si por alguna razón no puede usar este enfoque, aquí hay una heurística basada en una suposición que funciona para el 99% de todos los dominios:

Hay una propiedad que distingue (no todos, pero casi todos) los dominios "reales" de los subdominios y TLDs y ese es el registro MX del DNS. Puede crear un algoritmo que busque esto: Elimine las partes del nombre de host una por una y consulte el DNS hasta que encuentra un registro MX. Ejemplo:

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

Aquí hay un ejemplo en 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");
}
 9
Author: Francois Bourgeois,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-02-04 15:16:38

Acabo de escribir un programa para esto en clojure basado en la información de publicsuffix.org:

Https://github.com/isaksky/url_dom

Por ejemplo:

(parse "sub1.sub2.domain.co.uk") 
;=> {:public-suffix "co.uk", :domain "domain.co.uk", :rule-used "*.uk"}
 1
Author: Isak,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-03-20 15:54:39

Para una biblioteca C (con generación de tablas de datos en Python), escribí http://code.google.com/p/domain-registry-provider / que es rápido y eficiente en el espacio.

La biblioteca usa ~30kB para las tablas de datos y ~10kB para el código C. No hay sobrecarga de inicio ya que las tablas se construyen en tiempo de compilación. Véase http://code.google.com/p/domain-registry-provider/wiki/DesignDoc para más detalles.

Para comprender mejor el código de generación de tablas (Python), comience aquí: http://code.google.com/p/domain-registry-provider/source/browse/trunk/src/registry_tables_generator/registry_tables_generator.py

Para comprender mejor la API de C, consulte: http://code.google.com/p/domain-registry-provider/source/browse/trunk/src/domain_registry/domain_registry.h

 1
Author: Bryan McQuade,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-12-06 18:43:25

Como ya se ha dicho Public Suffix List es solo una forma de analizar el dominio correctamente. Para PHP puedes probar TLDExtract. Aquí está el código de ejemplo:

$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
Author: Alexander Fedyashov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-06-23 14:53:16

No está funcionando exactamente, pero tal vez podría obtener una respuesta útil tratando de recuperar el dominio pieza por pieza y verificando la respuesta, es decir, fetch ' http://uk ', luego ' http://co.uk ', luego ' http://domain.co.uk '. Cuando obtienes una respuesta sin error, tienes el dominio y el resto es subdominio.

A veces tienes que intentarlo :)

Editar:

Tom Leys señala en los comentarios, que algunos dominios están configurados solo en el subdominio www, que nos daría una respuesta incorrecta en la prueba anterior. Buen punto! Tal vez el mejor enfoque sería comprobar cada parte con ' http://www 'así como' http://', y contar un hit a cualquiera como un hit para esa sección del nombre de dominio? Todavía nos faltarían algunos arreglos 'alternativos' como 'web.domain.com', pero no me he encontrado con uno de esos por un tiempo:)

 0
Author: jTresidder,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-11-14 02:31:27

Utilice el UriBuilder entonces trae el UriBuilder.atributo host split it into an array on"." ahora tiene una matriz con el dominio dividido.

 0
Author: jrr,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-02-02 00:35:37
echo tld('http://www.example.co.uk/test?123'); // co.uk

/**
 * http://publicsuffix.org/
 * http://www.alandix.com/blog/code/public-suffix/
 * http://tobyinkster.co.uk/blog/2007/07/19/php-domain-class/
 */
function tld($url_or_domain = null)
{
    $domain = $url_or_domain ?: $_SERVER['HTTP_HOST'];
    preg_match('/^[a-z]+:\/\//i', $domain) and 
        $domain = parse_url($domain, PHP_URL_HOST);
    $domain = mb_strtolower($domain, 'UTF-8');
    if (strpos($domain, '.') === false) return null;

    $url = 'http://mxr.mozilla.org/mozilla-central/source/netwerk/dns/effective_tld_names.dat?raw=1';

    if (($rules = file($url)) !== false)
    {
        $rules = array_filter(array_map('trim', $rules));
        array_walk($rules, function($v, $k) use(&$rules) { 
            if (strpos($v, '//') !== false) unset($rules[$k]);
        });

        $segments = '';
        foreach (array_reverse(explode('.', $domain)) as $s)
        {
            $wildcard = rtrim('*.'.$segments, '.');
            $segments = rtrim($s.'.'.$segments, '.');

            if (in_array('!'.$segments, $rules))
            {
                $tld = substr($wildcard, 2);
                break;
            }
            elseif (in_array($wildcard, $rules) or 
                    in_array($segments, $rules))
            {
                $tld = $segments;
            }
        }

        if (isset($tld)) return $tld;
    }

    return false;
}
 0
Author: Mike,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-03-29 01:53:37

Acabo de escribir una biblioteca objc: https://github.com/kejinlu/KKDomain

 0
Author: Luke,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-04-07 06:08:13

Puede usar este tld lib .js: API JavaScript para trabajar contra nombres de dominio complejos, subdominios y URI.

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

Si está obteniendo el dominio raíz en el navegador. Puede usar este 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;
    }
  }
};

El uso de cookies es complicado.

 0
Author: xiaoyu2er,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-09 07:54:11

Lista de sufijos comunes (.co.uk,. com, etc.) para desnudarse junto con el http: / / y luego solo tendrá " sub.dominio "con el que trabajar en lugar de" http://sub.dominio.sufijo", o al menos eso es lo que probablemente haría.

El mayor problema es la lista de posibles sufijos. Después de todo, hay mucho.

 -1
Author: Peter C.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-11-14 01:00:17

Habiendo echado un vistazo rápido a la publicsuffix.org lista, parece que se podría hacer una aproximación razonable mediante la eliminación de los tres segmentos finales ("segmento" aquí significa una sección entre dos puntos) de los dominios donde el segmento final es de dos caracteres de largo, en el supuesto de que es un código de país y se subdividirá más. Si el segmento final es "nosotros" y el penúltimo segmento también tiene dos caracteres, elimine los últimos cuatro segmentos. En todos los demás casos, retire la los dos últimos segmentos. por ejemplo:

"ejemplo" no son dos caracteres, así que elimina "dominio.ejemplo", dejando "www"

"ejemplo" no son dos caracteres, así que elimina "dominio.ejemplo", dejando "super.duper "

"uk" son dos caracteres (pero no "us"), así que elimina "domain.co.uk", dejando "superusuario.duper "

"nosotros" es dos caracteres y es "nosotros", además de " wy " es también dos caracteres, por lo que eliminar "pvt.k12.wy.us", dejando "foo".

Tenga en cuenta que, aunque esto funciona para todos los ejemplos que he visto en las respuestas hasta ahora, sigue siendo solo una aproximación razonable. No es completamente correcto, aunque sospecho que es lo más cerca que es probable que se encuentre sin hacer / obtener una lista real para usar referencia.

 -3
Author: Dave Sherohman,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-11-14 18:25:18