Question

Obtenir le sous-domaine à partir d'une URL semble simple au début.

http://www.domain.example

Recherchez la première période puis renvoyez ce qui est arrivé après le " http: // " ...

Alors vous vous souvenez

http://super.duper.domain.example

Oh. Alors vous pensez, d'accord, trouver la dernière période, revenir en arrière et tout obtenir avant!

Alors vous vous souvenez

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

Et vous êtes de retour à la case départ. Quelqu'un a-t-il de bonnes idées en plus de stocker une liste de tous les TLD?

Était-ce utile?

La solution

  

Quelqu'un a-t-il de bonnes idées à part   stocker une liste de tous les TLD?

Non, car chaque TLD diffère par ce qui compte en tant que sous-domaine, domaine de second niveau, etc.

N'oubliez pas qu'il existe des domaines de premier niveau, des domaines de second niveau et des sous-domaines. Techniquement, tout sauf le TLD est un sous-domaine.

Dans l'exemple domain.com.uk, " domain " est un sous-domaine, " com " est un domaine de second niveau et "uk". est le TLD.

La question reste donc plus complexe qu’au premier abord et dépend de la manière dont chaque TLD est géré. Vous aurez besoin d'une base de données de tous les TLD comprenant leur partitionnement particulier, ainsi que ce qui compte comme domaine de second niveau et sous-domaine. Il n'y a pas trop de TLD, cependant, la liste est relativement gérable, mais collecter toutes ces informations n'est pas anodin. Une telle liste est peut-être déjà disponible.

On dirait que http://publicsuffix.org/ est l'une de ces listes - tous les suffixes courants (.com , .co.uk, etc.) dans une liste appropriée pour la recherche. Il ne sera toujours pas facile de l'analyser, mais au moins vous ne devez pas maintenir la liste.

  

Un "suffixe public" est celui sous lequel   Les internautes peuvent s'inscrire directement   des noms. Quelques exemples de public   les suffixes sont ".com", ".co.uk" et   "pvt.k12.wy.us". Le suffixe public   La liste est une liste de tous les publics connus   suffixes.

     

La liste des suffixes publics est un   initiative de la fondation Mozilla.   Il est disponible pour une utilisation dans   logiciel, mais a été créé à l'origine   pour répondre aux besoins du navigateur   fabricants. Il permet aux navigateurs de,   par exemple:

     
      
  • Évitez les "supercookies" " préjudiciables à la vie privée. être prêt pour   suffixes de nom de domaine de haut niveau
  •   
  • Mettez en surbrillance la partie la plus importante d'un nom de domaine chez l'utilisateur   interface
  •   
  • Triez avec précision les entrées d'historique par site
  •   

Consultation de la liste , vous pouvez voir que ce n'est pas un problème trivial. Je pense qu'une liste est le seul moyen correct d'y parvenir ...

Autres conseils

Comme le dit Adam, ce n’est pas facile et actuellement, le seul moyen pratique consiste à utiliser une liste.

Même dans ce cas, il existe des exceptions. Par exemple, dans .uk , il existe une poignée de domaines valides immédiatement à ce niveau qui ne figurent pas dans .co.uk . , il faut donc les ajouter comme exceptions.

C’est actuellement ce que font les principaux navigateurs - il est nécessaire de s’assurer que exemple.co.uk ne puisse pas définir de cookie pour .co.uk . être envoyé à un autre site Web sous .co.uk .

La bonne nouvelle est qu’une liste est déjà disponible sur http://publicsuffix.org/ .

Il existe également des travaux dans le IETF pour créer une sorte de standard pour permettre aux TLD de déclarer la structure de leur domaine. Ceci est toutefois légèrement compliqué par le biais de .uk.com , qui fonctionne comme s'il s'agissait d'un suffixe public, mais qui n'est pas vendu par le registre .com .

Publicsuffix.org semble être la solution. Il existe de nombreuses implémentations pour analyser facilement le contenu du fichier de données publicuffix:

Comme déjà dit par Adam et John, publicsuffix.org est la bonne solution. Mais si, pour une raison quelconque, vous ne pouvez pas utiliser cette approche, voici une heuristique basée sur une hypothèse qui fonctionne pour 99% des domaines:

Il existe une propriété qui distingue (pas tous, mais presque tous) "réel". domaines de sous-domaines et TLD et c'est l'enregistrement MX du DNS. Vous pouvez créer un algorithme qui recherche ceci: Supprimez les parties du nom d'hôte une par une et interrogez le DNS jusqu'à ce que vous trouviez un enregistrement MX. Exemple:

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

Voici un exemple 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");
}

Comme déjà dit, la liste des suffixes publics n'est qu'une des façons d'analyser correctement le domaine. Pour PHP, vous pouvez essayer TLDExtract . Voici un exemple de code:

$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'

Je viens juste d’écrire un programme pour cela en utilisant les informations de publicsuffix.org:

https://github.com/isaksky/url_dom

Par exemple:

(parse "sub1.sub2.domain.co.uk") 
;=> {:public-suffix "co.uk", :domain "domain.co.uk", :rule-used "*.uk"}

Pour une bibliothèque C (avec génération de table de données en Python), j’ai écrit http: //code.google.com/p/domain-registry-provider/ est à la fois rapide et économe en espace.

La bibliothèque utilise environ 30 Ko pour les tables de données et environ 10 Ko pour le code C. Il n'y a pas de surcharge de démarrage puisque les tables sont construites au moment de la compilation. Voir http://code.google.com/p/domain-registry- provider / wiki / DesignDoc pour plus de détails.

Pour mieux comprendre le code de génération de table (Python), commencez ici: http://code.google.com/p/domain-registry-provider/source/browse/trunk/src/registry_tables_generator/registry_tables_generator.py

Pour mieux comprendre l'API C, voir: http://code.google.com/p/domain-registry-provider/source/browse/trunk/src/domain_registry/domain_registry.h

Cela ne marche pas exactement, mais vous pourriez peut-être obtenir une réponse utile en essayant de récupérer le domaine, morceau par morceau, et en vérifiant la réponse, c.-à-d., récupérez ' http: // fr ", puis " http://co.uk ", puis " http://domain.co.uk ". Lorsque vous obtenez une réponse sans erreur, vous obtenez le domaine et le reste est un sous-domaine.

Parfois, il vous suffit de l'essayer :)

Modifier:

Tom Leys fait remarquer dans les commentaires que certains domaines sont configurés uniquement sur le sous-domaine www, ce qui nous donnerait une réponse incorrecte dans le test ci-dessus. Bon point! La meilleure approche serait peut-être de vérifier chaque partie avec ' http: // www ' ainsi qu'avec 'http: //', et de compter le nombre de résultats positifs. comme un succès pour cette section du nom de domaine? Il nous manque encore des arrangements «alternatifs» tels que «web.domain.com», mais je n’en ai pas rencontré depuis un moment:)

Utiliser URIBuilder puis obtenez l'attribut URIBUilder.host divisez-le en un tableau sur ". " vous avez maintenant un tableau avec le domaine divisé.

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;
}

Je viens d'écrire une bibliothèque objc: https://github.com/kejinlu/KKDomain

Vous pouvez utiliser cette bibliothèque tld.js: API JavaScript pour travailler avec des noms de domaine complexes, des sous-domaines et des URI .

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

Si vous obtenez le domaine racine dans le navigateur. Vous pouvez utiliser cette bibliothèque 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;
    }
  }
};

L'utilisation d'un cookie est délicate.

Si vous souhaitez extraire des sous-domaines et / ou des domaines à partir d'une liste arbitraire d'URL, ce script python peut être utile. Attention cependant, ce n'est pas parfait. C’est un problème délicat à résoudre en général et il est très utile si vous avez une liste blanche des domaines que vous attendez.

  1. Obtenir les domaines de premier niveau de 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. Générer une expression rationnelle
import re

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

subdomain_regex = r'/([^/]*)\.[^/.]+\.({})/.*

  1. Utiliser une expression régulière sur la liste des 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)
.format(_regex) domain_regex = r'([^/.]+\.({}))/.*
  1. Utiliser une expression régulière sur la liste des URL
<*>.format(_regex)
  1. Utiliser une expression régulière sur la liste des URL
<*>

Liste des suffixes courants (.co.uk, .com, etc.) à supprimer avec le http: // et vous ne disposez alors que de "sub.domain". pour travailler avec au lieu de http: //sub.domain.suffix " ;, ou du moins c'est ce que Je ferais probablement.

Le plus gros problème est la liste des suffixes possibles. Il y en a beaucoup, après tout.

Après avoir jeté un coup d’œil à la liste publicsuffix.org, il apparaît que vous pouvez faire une approximation raisonnable en supprimant les trois derniers segments ("segment", qui signifie ici une section entre deux points) des domaines dans lesquels se trouve le segment final. deux caractères de long, en supposant que c'est un code de pays et sera subdivisé. Si le dernier segment est "nous". et l'avant-dernier segment contient également deux caractères, supprimez les quatre derniers segments. Dans tous les autres cas, supprimez les deux derniers segments. par exemple:

" exemple " n'est pas deux caractères, supprimez donc "domaine.exemple", en laissant "www"

" exemple " n'est pas deux caractères, supprimez donc "domaine.exemple", en laissant "super.duper"

& uk; uk " est composé de deux caractères (mais pas "us"), supprimez donc "domain.co.uk", en laissant "super.duper"

" nous " est composé de deux caractères et est "nous", plus "wy". est également deux caractères, donc supprimez "pvt.k12.wy.us", en laissant "foo".

Notez que, bien que cela fonctionne pour tous les exemples que j'ai vus dans les réponses jusqu'à présent, cela ne reste qu'une approximation raisonnable. Ce n’est pas tout à fait correct, même si je suppose que c’est à peu près aussi proche que possible de la création ou de l’obtention d’une liste à utiliser comme référence.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top