web-dev-qa-db-ger.com

wie erhalte ich den Domainnamen von der URL?

Wie kann ich einen Domainnamen aus einer URL-Zeichenfolge abrufen?

Beispiele:

+----------------------+------------+
| input                | output     |
+----------------------+------------+
| www.google.com       | google     |
| www.mail.yahoo.com   | mail.yahoo |
| www.mail.yahoo.co.in | mail.yahoo |
| www.abc.au.uk        | abc        |
+----------------------+------------+

Verbunden:

45
Chinmay

Ich musste einmal einen solchen Regex für eine Firma schreiben, für die ich arbeitete. Die Lösung war:

  • Rufen Sie eine Liste aller verfügbaren ccTLD und gTLD ab. Ihr erster Halt sollte IANA sein. Die Liste von Mozilla sieht auf den ersten Blick gut aus, es fehlt jedoch beispielsweise ac.uk, so dass sie nicht wirklich verwendbar ist.
  • Treten Sie der Liste wie im folgenden Beispiel bei. Eine Warnung: Bestellung ist wichtig! Wenn org.uk nach uk erscheinen würde, dann example.org.uk würde mit org anstelle von Beispiel übereinstimmen.

Beispiel Regex:

.*([^\.]+)(com|net|org|info|coop|int|co\.uk|org\.uk|ac\.uk|uk|__and so on__)$

Dies funktionierte sehr gut und passte auch zu seltsamen, inoffiziellen Top-Levels wie de.com und Freunden.

Die Oberseite:

  • Sehr schnell, wenn Regex optimal bestellt ist

Der Nachteil dieser Lösung ist natürlich:

  • Handgeschriebener regulärer Ausdruck, der manuell aktualisiert werden muss, wenn ccTLDs geändert oder hinzugefügt werden. Mühsamer Job!
  • Sehr großer regulärer Ausdruck, daher nicht sehr lesbar.
40
pi.
/^(?:www\.)?(.*?)\.(?:com|au\.uk|co\.in)$/
12
jfs

Das exakte Extrahieren des Domänennamens kann recht kompliziert sein, da die Domänenerweiterung zwei Teile enthalten kann (z. B. .com.au oder .co.uk) und die Unterdomäne (das Präfix) möglicherweise vorhanden ist. Das Auflisten aller Domain-Erweiterungen ist nicht möglich, da es Hunderte davon gibt. EuroDNS.com listet beispielsweise über 800 Domainnamen-Erweiterungen auf.

Ich habe daher eine kurze PHP-Funktion geschrieben, die 'parse_url ()' und einige Beobachtungen zu Domain-Erweiterungen verwendet, um die URL-Komponenten UND den Domain-Namen genau zu extrahieren. Die Funktion ist wie folgt:

function parse_url_all($url){
    $url = substr($url,0,4)=='http'? $url: 'http://'.$url;
    $d = parse_url($url);
    $tmp = explode('.',$d['Host']);
    $n = count($tmp);
    if ($n>=2){
        if ($n==4 || ($n==3 && strlen($tmp[($n-2)])<=3)){
            $d['domain'] = $tmp[($n-3)].".".$tmp[($n-2)].".".$tmp[($n-1)];
            $d['domainX'] = $tmp[($n-3)];
        } else {
            $d['domain'] = $tmp[($n-2)].".".$tmp[($n-1)];
            $d['domainX'] = $tmp[($n-2)];
        }
    }
    return $d;
}

Diese einfache Funktion funktioniert in fast allen Fällen. Es gibt einige Ausnahmen, aber diese sind sehr selten.

Um diese Funktion zu demonstrieren/testen, können Sie Folgendes verwenden:

$urls = array('www.test.com', 'test.com', 'cp.test.com' .....);
echo "<div style='overflow-x:auto;'>";
echo "<table>";
echo "<tr><th>URL</th><th>Host</th><th>Domain</th><th>Domain X</th></tr>";
foreach ($urls as $url) {
    $info = parse_url_all($url);
    echo "<tr><td>".$url."</td><td>".$info['Host'].
    "</td><td>".$info['domain']."</td><td>".$info['domainX']."</td></tr>";
}
echo "</table></div>";

Die Ausgabe für die aufgeführten URLs lautet wie folgt:

 enter image description here

Wie Sie sehen, werden der Domänenname und der Domänenname ohne die Erweiterung unabhängig von der URL, die der Funktion angezeigt wird, konsistent extrahiert.

Ich hoffe, dass das hilft.

8
Clinton

Ich kenne keine Bibliotheken, aber die String-Manipulation von Domain-Namen ist leicht genug. 

Der schwierige Teil ist zu wissen, ob der Name auf der zweiten oder dritten Ebene liegt. Dazu benötigen Sie eine Datei, die Sie pflegen (z. B. für .uk ist nicht immer die dritte Ebene, einige Organisationen (z. B. bl.uk, jet.uk) sind auf der zweiten Ebene vorhanden).

Die source von Firefox von Mozilla enthält eine solche Datei. Überprüfen Sie die Lizenzierung von Mozilla, um zu sehen, ob Sie diese wiederverwenden können.

4
Richard

Es gibt zwei Möglichkeiten

Mit split

Dann parsen Sie einfach diese Zeichenfolge

var domain;
//find & remove protocol (http, ftp, etc.) and get domain
if (url.indexOf('://') > -1) {
    domain = url.split('/')[2];
} if (url.indexOf('//') === 0) {
    domain = url.split('/')[2];
} else {
    domain = url.split('/')[0];
}

//find & remove port number
domain = domain.split(':')[0];

Regex verwenden

 var r = /:\/\/(.[^/]+)/;
 "http://stackoverflow.com/questions/5343288/get-url".match(r)[1] 
 => stackoverflow.com

Hoffe das hilft

4
Fizer Khan
import urlparse

GENERIC_TLDS = [
    'aero', 'asia', 'biz', 'com', 'coop', 'edu', 'gov', 'info', 'int', 'jobs', 
    'mil', 'mobi', 'museum', 'name', 'net', 'org', 'pro', 'tel', 'travel', 'cat'
    ]

def get_domain(url):
    hostname = urlparse.urlparse(url.lower()).netloc
    if hostname == '':
        # Force the recognition as a full URL
        hostname = urlparse.urlparse('http://' + uri).netloc

    # Remove the 'user:passw', 'www.' and ':port' parts
    hostname = hostname.split('@')[-1].split(':')[0].lstrip('www.').split('.')

    num_parts = len(hostname)
    if (num_parts < 3) or (len(hostname[-1]) > 2):
        return '.'.join(hostname[:-1])
    if len(hostname[-2]) > 2 and hostname[-2] not in GENERIC_TLDS:
        return '.'.join(hostname[:-1])
    if num_parts >= 3:
        return '.'.join(hostname[:-2])

Es kann nicht garantiert werden, dass dieser Code mit allen URLs funktioniert, und sie filtert keine grammatikalisch korrekten, aber ungültigen wie "example.uk". 

In den meisten Fällen wird es jedoch funktionieren.

3

Es ist nicht möglich, ohne eine TLD-Liste zu vergleichen, da es viele Fälle gibt, wie http://www.db.de/ oder http://bbc.co.uk/ von einem Regex als die Domänen db.de (korrekt) und co.uk (falsch) interpretiert.

Aber auch dann haben Sie keinen Erfolg, wenn Ihre Liste auch keine SLDs enthält. URLs wie http://big.uk.com/ und http://www.uk.com/ werden beide als uk.com interpretiert (die erste Domäne ist big.uk.com).

Aus diesem Grund verwenden alle Browser die öffentliche Suffix-Liste von Mozilla:

https://en.wikipedia.org/wiki/Public_Suffix_List

Sie können es in Ihrem Code verwenden, indem Sie es über diese URL importieren: 

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

Fühlen Sie sich frei, meine Funktion zu erweitern, um nur den Domänennamen zu extrahieren. Es wird kein Regex verwendet und es ist schnell:

http://www.programmierer-forum.de/domainnamen-ermitteln-t244185.htm#3471878

2
mgutt

Grundsätzlich wollen Sie:

google.com        -> google.com    -> google
www.google.com    -> google.com    -> google
google.co.uk      -> google.co.uk  -> google
www.google.co.uk  -> google.co.uk  -> google
www.google.org    -> google.org    -> google
www.google.org.uk -> google.org.uk -> google

Wahlweise:

www.google.com     -> google.com    -> www.google
images.google.com  -> google.com    -> images.google
mail.yahoo.co.uk   -> yahoo.co.uk   -> mail.yahoo
mail.yahoo.com     -> yahoo.com     -> mail.yahoo
www.mail.yahoo.com -> yahoo.com     -> mail.yahoo

Sie müssen keinen sich ständig ändernden Regex erstellen, da 99% der Domains korrekt abgeglichen werden, wenn Sie nur den zweitletzten Teil des Namens betrachten:

(co|com|gov|net|org)

Wenn es einer von diesen ist, müssen Sie 3 Punkte zusammenbringen, sonst 2. Einfach. Nun ist meine Regex-Zauberei nicht mit der von anderen SOern vergleichbar. Daher habe ich den besten Weg gefunden, dies mit etwas Code zu erreichen, vorausgesetzt, Sie haben den Pfad bereits verlassen:

 my @d=split /\./,$domain;                # split the domain part into an array
 [email protected];                                   # count how many parts
 $dest=$d[$c-2].'.'.$d[$c-1];             # use the last 2 parts
 if ($d[$c-2]=~m/(co|com|gov|net|org)/) { # is the second-last part one of these?
   $dest=$d[$c-3].'.'.$dest;              # if so, add a third part
 };
 print $dest;                             # show it

Um nur den Namen gemäß Ihrer Frage zu erfahren:

 my @d=split /\./,$domain;                # split the domain part into an array
 [email protected];                                   # count how many parts
 if ($d[$c-2]=~m/(co|com|gov|net|org)/) { # is the second-last part one of these?
   $dest=$d[$c-3];                        # if so, give the third last
   $dest=$d[$c-4].'.'.$dest if ($c>3);    # optional bit
 } else {
   $dest=$d[$c-2];                        # else the second last
   $dest=$d[$c-3].'.'.$dest if ($c>2);    # optional bit 
 };
 print $dest;                             # show it

Ich mag diesen Ansatz, weil er wartungsfrei ist. Es sei denn, Sie möchten bestätigen, dass es sich tatsächlich um eine legitime Domäne handelt. Dies ist jedoch sinnlos, da Sie dies höchstwahrscheinlich nur zur Verarbeitung von Protokolldateien verwenden und eine ungültige Domäne erst gar nicht dort eintritt.

Wenn Sie "inoffizielle" Subdomains wie bozo.za.net oder bozo.au.uk zuordnen möchten, fügen Sie bozo.msf.ru einfach (za | au | msf) zur Regex hinzu.

Ich würde gerne jemanden sehen, der all dies mit einer Regex macht. Ich bin mir sicher, dass es möglich ist.

2
dagelf

/[^w{3}\.]([a-zA-Z0-9]([a-zA-Z0-9\-]{0,65}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,6}/gim

die Verwendung dieses JavaScript-Regex ignoriert das WWW und die folgenden Punkte, wobei die Domain intakt bleibt. stimmt auch nicht mit www und cc tld überein

1
stancoffyn

Verwenden Sie diesen (.) (. *?) (.) Dann extrahieren Sie einfach die Anfangs- und Endpunkte. Einfach richtig?

0
pabben
  1. wie ist das

    =((?:(?:(?:http)s?:)?\/\/)?(?:(?:[a-zA-Z0-9]+)\.?)*(?:(?:[a-zA-Z0-9]+))\.[a-zA-Z0-9]{2,3}) (Sie können "\ /" am Ende des Musters hinzufügen

  2. wenn Ihr Ziel darin besteht, URLs, die als Parameter übergeben wurden, zu löschen, können Sie das Gleichheitszeichen als erstes Zeichen hinzufügen.

    = ((? :(? :( ?: http) s?:)? //)? (?: (?: [a-zA-Z0-9] +).?) * (?: (?: [ a-zA-Z0-9] +)). [a-zA-Z0-9] {2,3} /)

    und durch "/" ersetzen

Das Ziel dieses Beispiels ist es, jeden Domänennamen unabhängig von der Form zu entfernen, in der er angezeigt wird. (D. H. Um sicherzustellen, dass URL-Parameter keine Domänennamen enthalten, um einen xss-Angriff zu vermeiden)

0
Chaim Klar

Sie benötigen eine Liste der Domain-Präfixe und Suffixe, die entfernt werden können. Zum Beispiel:

Präfixe:

  • www.

Suffixe:

  • .com
  • .co.in
  • .au.uk
0
Gumbo

Zu einem bestimmten Zweck habe ich gestern diese schnelle Python-Funktion ausgeführt. Die Domain wird von der URL zurückgegeben. Es ist schnell und benötigt keine Eingabedateien. Ich gebe nicht vor, dass es in allen Fällen funktioniert, aber es erfüllt wirklich die Arbeit, die ich für ein einfaches Text-Mining-Skript benötige.

Die Ausgabe sieht folgendermaßen aus: 

http://www.google.co.uk => google.co.uk
http://24.media.tumblr.com/tumblr_m04s34rqh567ij78k_250.gif => tumblr.com

def getDomain(url):    
        parts = re.split("\/", url)
        match = re.match("([\w\-]+\.)*([\w\-]+\.\w{2,6}$)", parts[2]) 
        if match != None:
            if re.search("\.uk", parts[2]): 
                match = re.match("([\w\-]+\.)*([\w\-]+\.[\w\-]+\.\w{2,6}$)", parts[2])
            return match.group(2)
        else: return ''  

Scheint ziemlich gut zu funktionieren.
Es muss jedoch so geändert werden, dass Domänenerweiterungen bei der Ausgabe wie gewünscht entfernt werden.

0
binnie

Ich weiß, dass die Frage nach einer Regex-Lösung sucht, aber bei jedem Versuch wird es nicht funktionieren, alles abzudecken

Ich habe mich entschieden, diese Methode in Python zu schreiben, die nur mit URLs funktioniert, die eine Subdomain haben (d. H. Www.mydomain.co.uk) und keine Subdomains mit mehreren Ebenen wie www.mail.yahoo.com

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:])}
0
Korayem

Wenn Sie also nur einen String und keinen window.location haben, könnten Sie ...

String.prototype.toUrl = function(){

if(!this && 0 < this.length)
{
    return undefined;
}
var original = this.toString();
var s = original;
if(!original.toLowerCase().startsWith('http'))
{
    s = 'http://' + original;
}

s = this.split('/');

var protocol = s[0];
var Host = s[2];
var relativePath = '';

if(s.length > 3){
    for(var i=3;i< s.length;i++)
    {
        relativePath += '/' + s[i];
    }
}

s = Host.split('.');
var domain = s[s.length-2] + '.' + s[s.length-1];    

return {
    original: original,
    protocol: protocol,
    domain: domain,
    Host: Host,
    relativePath: relativePath,
    getParameter: function(param)
    {
        return this.getParameters()[param];
    },
    getParameters: function(){
        var vars = [], hash;
        var hashes = this.original.slice(this.original.indexOf('?') + 1).split('&');
        for (var i = 0; i < hashes.length; i++) {
            hash = hashes[i].split('=');
            vars.Push(hash[0]);
            vars[hash[0]] = hash[1];
        }
        return vars;
    }
};};

Wie benutzt man.

var str = "http://en.wikipedia.org/wiki/Knopf?q=1&t=2";
var url = str.toUrl;

var Host = url.Host;
var domain = url.domain;
var original = url.original;
var relativePath = url.relativePath;
var paramQ = url.getParameter('q');
var paramT = url.getParamter('t');
0
Thomas Paris