2010-01-28 20 views
31

Sto cercando di estrarre solo il nome di dominio da una stringa URL. Ho quasi l'ho ... Sto usando URIOttieni solo il nome di dominio da un URL?

ho una stringa di .. il mio primo pensiero è stato quello di utilizzare Regex, ma poi ho deciso di utilizzare la classe URI

http://www.google.com/url?sa=t&source=web&ct=res&cd=1&ved=0CAgQFjAA&url=http://www.test.com/&rct=j&q=test&ei=G2phS-HdJJWTjAfckvHJDA&usg=AFQjCNFSEAztaqtkaIvEzxmRm2uOARn1kQ

ho bisogno di convertire il sopra a google.com e Google senza il www

ho fatto la seguente

Uri test = new Uri(referrer); 
log.Info("Domain part : " + test.Host); 

Fondamentalmente questo restituisce www.google.com .... vorrei t o cercare di tornare 2 forme se possibile ... come già detto ...

google.com e google

Questo è possibile con URI?

+3

Quale dovrebbe essere la conseguenza essere per 'foo.bar.com'? Che mi dici di "foo.co.uk"? Che mi dici di "foo.bar.museum"? –

+0

Ciao Mark ... fondamentalmente sto seguendo il nome di dominio puro ... quindi se inizia con ww3.test.co.uk allora dovrebbe restituire test.co.uk dato che questo è il dominio puro .... Quindi nel tuo esempio foo.co.uk dovrebbe restituire foo.co.uk dato che questo è il dominio puro .... e foo.bar.museum restituirebbe bar.museum ma. il museo non è un dominio di primo livello valido come .com, co.uk, .us ecc. è ??? ... –

+2

.museum, .mobi e .travel sono nomi di dominio di primo livello perfettamente validi. Potresti chiarire, per favore, perché ww3 non fa parte del nome di dominio 'puro', mentre è foo? Qual è la * tua * definizione di un nome di dominio puro? –

risposta

31

Sì, è possibile uso:

Uri.GetLeftPart(UriPartial.Authority) 
+1

Grazie Dewfy, ma questo in realtà restituisce http://www.google.com .. da qui l'http: // e il www che è ciò di cui non ho bisogno –

+7

In realtà ho avuto modo di restituire lo stesso senza http:// ma ha il www ... usando Uri.Host –

+0

hai letto la domanda? restituisce httr: //www.google.com – Toolkit

6

google.com non è garantito essere lo stesso come www.google.com (bene, per questo esempio è tecnicamente, ma può essere altrimenti).

forse quello che ti serve è in realtà rimuovere il dominio "top level" e la sottodella "www"? Quindi solo split('.') e prendi la parte prima dell'ultima parte!

+1

"google.com non è garantito per essere uguale a www.google.com" - e infatti non è lo stesso :) –

+1

omg, davvero. www.google.com = 209.85.129.104, google.com = 209.85.129.147 :-) – naivists

+0

ingenui: il dominio è lo stesso, il server contiene gli IP di bilanciamento del carico su richiesta –

3

Penso che tu stia mostrando un fraintendimento di ciò che costituisce un "nome di dominio" - non esiste un "puro nome di dominio" nell'uso comune - questo è qualcosa che dovrai definire se vuoi ottenere risultati coerenti.
Vuoi semplicemente togliere la parte "www"? E poi un'altra versione che rimuove il dominio di primo livello (ad esempio, rimuovere le parti ".com" o ".co.uk" ecc.) Un'altra risposta cita la divisione (".") - sarà necessario usa qualcosa di simile se vuoi escludere parti specifiche del nome host manualmente, non c'è nulla all'interno del framework .NET che soddisfi esattamente le tue esigenze - dovrai implementare queste cose tu stesso.

-1

A causa delle numerose variazioni nei nomi di dominio e l'inesistenza di un elenco autorevole di ciò che costituisce un "dominio di dominio puro" come descrivi, ho appena fatto ricorso a Uri.Host in passato. Per evitare casi in cui www.google.com e google.com si presentano come due domini diversi, ho spesso fatto ricorso a stripping del www. da tutti i domini che lo contengono, poiché è quasi garantito (ALMOST) di puntare allo stesso sito. È davvero l'unico modo semplice per farlo senza rischiare di perdere alcuni dati.

blog
17

@Dewfy: difetto è che il metodo restituisce "uk" per "www.test.co.uk" ma il dominio qui è chiaramente "test.co.uk".

@naivists: difetto è che il metodo restituisce "beta.microsoft.com" per "www.beta.microsoft.com", ma il dominio qui è chiaramente "microsoft.com"

ho bisogno lo stesso, così ho scritto una classe che puoi copiare e incollare nella tua soluzione. Usa una serie di stringhe hard coded di tld.http://pastebin.com/raw.php?i=VY3DCNhp

Console.WriteLine(GetDomain.GetDomainFromUrl("http://www.beta.microsoft.com/path/page.htm")); 

uscite microsoft.com

e

Console.WriteLine(GetDomain.GetDomainFromUrl("http://www.beta.microsoft.co.uk/path/page.htm")); 

uscite microsoft.co.uk

+0

Solo un rapido heads-up che la classe pastebin non aveva. org.uk, .co.uk o .ac.uk in realtà aggiunti all'elenco di TLD. Quindi, casualmente, l'esempio sopra non funziona finché non li aggiungi. – highace

+0

@servermanfail, grazie per l'ottimo codice. Esattamente quello di cui avevo bisogno! – Phil

+8

Questo non funzionerà più quando le centinaia di nuovi gTLD saranno disponibili entro la fine dell'anno e l'anno prossimo ... a meno che qualcuno non li aggiunga manualmente. – Ricketts

5

Di seguito è riportato un codice che darà solo lo SLD più gTLD o ccTLD estensione (si noti l'eccezione di seguito). Non mi interessa il DNS.

La teoria è la seguente:

  • nulla sotto 3 gettoni rimane come è ad esempio "Localhost", "domain.com", altrimenti: l'ultimo token deve essere un'estensione gTLD o ccTLD.
  • Il token penultima è considerato parte dell'estensione se si tratta di lunghezza < 3 O se incluso in un elenco di eccezioni.
  • Infine il token prima che uno è considerato lo SLD. Qualsiasi cosa prima è considerata un sottodominio o un qualificatore di host, ad es. Www.

Per quanto riguarda il codice, breve & dolce:

private static string GetDomainName(string url) 
{ 
    string domain = new Uri(url).DnsSafeHost.ToLower(); 
    var tokens = domain.Split('.'); 
    if (tokens.Length > 2) 
    { 
     //Add only second level exceptions to the < 3 rule here 
     string[] exceptions = { "info", "firm", "name", "com", "biz", "gen", "ltd", "web", "net", "pro", "org" }; 
     var validTokens = 2 + ((tokens[tokens.Length - 2].Length < 3 || exceptions.Contains(tokens[tokens.Length - 2])) ? 1 : 0); 
     domain = string.Join(".", tokens, tokens.Length - validTokens, validTokens); 
    } 
    return domain; 
} 

L'eccezione ovvia è che questo non sarà che fare con i nomi di dominio 2 lettere. Quindi se sei abbastanza fortunato da possedere ab.com dovrai adattare leggermente il codice. Per noi comuni mortali questo codice coprirà quasi tutti i gTLD e ccTLD, meno un paio di quelli molto esotiche.

1

L'host di Uri restituisce sempre dominio (www.google.com), inclusa un'etichetta (www) e un dominio di primo livello (com). Ma spesso vorresti estrarre la parte centrale. Semplicemente faccio

Uri uri; 
bool result = Uri.TryCreate(returnUri, UriKind.Absolute, out uri); 
if (result == false) 
    return false; 

//if you are sure it's not "localhost" 
string domainParts = uri.Host.Split('.'); 
string topLevel = domainParts[domainParts.Length - 1] 
string hostBody = domainParts[domainParts.Length - 2] 
string label = domainParts[domainParts.Length - 3] 

ma si ha bisogno di controllare domainParts.length, come spesso l'URI è come "google.com".

-1
string domain = new Uri(HttpContext.Current.Request.Url.AbsoluteUri).GetLeftPart(UriPartial.Authority); 
5

Ho provato praticamente tutti gli approcci, ma non tutti sono riusciti a ottenere il risultato desiderato. Così qui è il mio approccio regolato da servermanfail.

Il file TLD è disponibile sul https://publicsuffix.org/list/ ho preso il file da https://publicsuffix.org/list/effective_tld_names.dat analizzarlo e cercare il TLD. Se vengono pubblicati nuovi tld, scarica l'ultimo file.

divertirsi.

using System; 
using System.Collections.Generic; 
using System.IO; 

namespace SearchWebsite 
{ 
internal class NetDomain 
{ 
    static public string GetDomainFromUrl(string Url) 
    { 
     return GetDomainFromUrl(new Uri(Url)); 
    } 

    static public string GetDomainFromUrl(string Url, bool Strict) 
    { 
     return GetDomainFromUrl(new Uri(Url), Strict); 
    } 

    static public string GetDomainFromUrl(Uri Url) 
    { 
     return GetDomainFromUrl(Url, false); 
    } 

    static public string GetDomainFromUrl(Uri Url, bool Strict) 
    { 
     initializeTLD(); 
     if (Url == null) return null; 
     var dotBits = Url.Host.Split('.'); 
     if (dotBits.Length == 1) return Url.Host; //eg http://localhost/blah.php = "localhost" 
     if (dotBits.Length == 2) return Url.Host; //eg http://blah.co/blah.php = "localhost" 
     string bestMatch = ""; 
     foreach (var tld in DOMAINS) 
     { 
      if (Url.Host.EndsWith(tld, StringComparison.InvariantCultureIgnoreCase)) 
      { 
       if (tld.Length > bestMatch.Length) bestMatch = tld; 
      } 
     } 
     if (string.IsNullOrEmpty(bestMatch)) 
      return Url.Host; //eg http://domain.com/blah = "domain.com" 

     //add the domain name onto tld 
     string[] bestBits = bestMatch.Split('.'); 
     string[] inputBits = Url.Host.Split('.'); 
     int getLastBits = bestBits.Length + 1; 
     bestMatch = ""; 
     for (int c = inputBits.Length - getLastBits; c < inputBits.Length; c++) 
     { 
      if (bestMatch.Length > 0) bestMatch += "."; 
      bestMatch += inputBits[c]; 
     } 
     return bestMatch; 
    } 


    static private void initializeTLD() 
    { 
     if (DOMAINS.Count > 0) return; 

     string line; 
     StreamReader reader = File.OpenText("effective_tld_names.dat"); 
     while ((line = reader.ReadLine()) != null) 
     { 
      if (!string.IsNullOrEmpty(line) && !line.StartsWith("//")) 
      { 
       DOMAINS.Add(line); 
      } 
     } 
     reader.Close(); 
    } 


    // This file was taken from https://publicsuffix.org/list/effective_tld_names.dat 

    static public List<String> DOMAINS = new List<String>(); 
} 

}

+2

Ho usato la tua soluzione e ha funzionato abbastanza bene fino a quando ho scoperto alcuni bug. Ad esempio, 'www.navistar.com' non elimina la parte' www'. Questa è la correzione 'if (! Url.Host.EndsWith (". "+ Tld, StringComparison.InvariantCultureIgnoreCase)) continua;' – wpfwannabe

1

Usa Nager.PublicSuffix

install-pacchetto Nager.PublicSuffix

var domainParser = new DomainParser(new WebTldRuleProvider()); 

var domainName = domainParser.Get("sub.test.co.uk"); 
//domainName.Domain = "test"; 
//domainName.Hostname = "sub.test.co.uk"; 
//domainName.RegistrableDomain = "test.co.uk"; 
//domainName.SubDomain = "sub"; 
//domainName.TLD = "co.uk"; 
Problemi correlati