2010-01-28 11 views
31

Estoy tratando de extraer solo el nombre de dominio de una cadena de URL. Casi lo tengo ... Estoy utilizando URIObtener solo el nombre de dominio de una URL?

tengo una cadena .. lo primero que pensé fue utilizar expresiones regulares pero luego decidió utilizar la clase 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

que necesito para convertir el anterior a google.com y Google sin la www

hice lo siguiente

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

Básicamente esto devuelve www.google.com .... me gustaría t o tratar de volver 2 formas si es posible ... ... como se mencionó

google.com y Google

¿Es esto posible con URI?

+3

Lo que debería ser el resultado de 'foo.bar.com'? ¿Qué hay de 'foo.co.uk'? ¿Qué hay de 'foo.bar.museum'? –

+0

Hola Mark ... básicamente busco el nombre de dominio puro ... así que si comienza con ww3.test.co.uk entonces debería devolver test.co.uk ya que este es el dominio puro ... Entonces en su ejemplo, foo.co.uk debe devolver foo.co.uk ya que este es el dominio puro .... y foo.bar.museum devolverá bar.museum pero. el museo no es un dominio de nivel superior válido como .com, co.uk, .us, etc. ¿es eso? ... –

+2

.museum, .mobi y .travel son nombres de dominio de nivel superior perfectamente válidos. ¿Podría aclarar por qué ww3 no es parte del nombre de dominio "puro", mientras que foo es? ¿Cuál es * la * definición de un nombre de dominio puro? –

Respuesta

31

Sí, es posible utilización:

Uri.GetLeftPart(UriPartial.Authority) 
+1

Gracias Dewfy, pero esto en realidad devuelve http://www.google.com .. de ahí el http: // y el www que es lo que no necesito –

+7

De hecho lo devolví sin el http:// pero tiene el www ... usando Uri.Host –

+0

¿has leído la pregunta? esto devuelve http: //www.google.com – Toolkit

6

google.com no se garantiza que sea el mismo que www.google.com (bueno, para este ejemplo que técnicamente es, pero puede ser de otra manera).

tal vez lo que necesita es en realidad eliminar el dominio "nivel superior" y el subdominio "www"? ¡Entonces solo split('.') y toma la parte antes de la última parte!

+1

"google.com no garantiza que sea el mismo que www.google.com" - y de hecho no es lo mismo :) –

+1

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

+0

naivists: El dominio es el mismo, el servidor tiene IP de equilibrio de carga bajo pedido –

3

Creo que está mostrando un malentendido sobre lo que constituye un "nombre de dominio"; no existe el "nombre de dominio puro" en el uso común; esto es algo que deberá definir si desea resultados consistentes.
¿Simplemente quiere quitar la parte "www"? Y luego tiene otra versión que quita el dominio de nivel superior (por ejemplo, quitar las partes ".com" o ".co.uk", etc.) Otra respuesta menciona división (".") - necesitará use algo como esto si desea excluir partes específicas del nombre de host de forma manual, no hay nada dentro del marco de .NET que cumpla con sus requisitos exactamente; deberá implementar estas cosas usted mismo.

-1

Debido a las numerosas variaciones en los nombres de dominio y la inexistencia de una lista auténtica de lo que constituye un "nombre de dominio puro" como usted describe, acabo de recurrir al uso de Uri.Host en el pasado. Para evitar casos en los que www.google.com y google.com aparecen como dos dominios diferentes, a menudo he recurrido a eliminar el www. de todos los dominios que lo contienen, ya que está casi garantizado (ALMOST) apuntar al mismo sitio. Realmente es la única manera simple de hacerlo sin arriesgar perder algunos datos.

el blog
17

@Dewfy: defecto es que los devuelve el método "uk" para "www.test.co.uk" pero el dominio aquí es claramente "test.co.uk".

@naivists: defecto es que el método devuelve "beta.microsoft.com" para "www.beta.microsoft.com", pero el dominio aquí es claramente "microsoft.com"

que necesitan el mismo, entonces escribí una clase que puedes copiar y pegar en tu solución. Utiliza una matriz de cadenas codificadas de tld.http://pastebin.com/raw.php?i=VY3DCNhp

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

salidas microsoft.com

y

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

salidas microsoft.co.uk

+0

Solo un aviso rápido que la clase pastebin no tenía. org.uk, .co.uk o .ac.uk realmente se agregaron a la lista de TLD. Entonces, casualmente, el ejemplo anterior en realidad no funciona hasta que los agregas. – highace

+0

@servermanfail, gracias por el excelente código. ¡Exactamente lo que necesitaba! – Phil

+8

Esto dejará de funcionar cuando los cientos de gTLD nuevos estén disponibles a finales de este año y el próximo ... a menos que alguien los agregue manualmente. – Ricketts

1

Sí, he publicado aquí la solución: http://pastebin.com/raw.php?i=raxNQkCF

Si desea eliminar el correo xtension sólo tiene que añadir

if (url.indexof(".")>-1) {url = url.substring(0, url.indexof("."))}

5

A continuación se muestra un código que le dará sólo el SLD además de gTLD o ccTLD extensión (tenga en cuenta la excepción abajo). No me importa el DNS.

La teoría es la siguiente:

  • cualquier cosa bajo 3 tokens permanece como es por ejemplo "localhost", "domain.com"; de lo contrario: el último token debe ser una extensión de gTLD o ccTLD.
  • La penúltima ficha se considera parte de la extensión si su longitud es < 3 O si está incluida en una lista de excepciones.
  • Finalmente, el token anterior a ese se considera SLD. Todo lo anterior se considera un subdominio o un calificador de host, p. Www.

En cuanto al código, corta & dulce:

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

La excepción obvia es que esto no va a hacer frente a los nombres de dominio de 2 letras. Por lo tanto, si tienes la suerte de ser propietario de ab.com, deberás adaptar el código un poco. Para nosotros simples mortales, este código cubrirá casi todos los gTLD y ccTLD, menos algunos muy exóticos.

1

Uri's Host siempre devuelve dominio (www.google.com), incluyendo una etiqueta (www) y un dominio de nivel superior (com). Pero a menudo querrás extraer el bit del medio. Simplemente hago

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] 

pero sí es necesario para comprobar domainParts.length, ya que a menudo el URI dada es como "google.com".

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

Probé prácticamente todos los enfoques, pero ninguno de ellos alcanzó el resultado deseado. Así que aquí está mi enfoque ajustado desde servermanfail.

El archivo tld está disponible en https://publicsuffix.org/list/ He tomado el archivo de https://publicsuffix.org/list/effective_tld_names.dat y lo he buscado. Si se publican nuevos tld, simplemente descargue el archivo más reciente.

diviértete.

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

He utilizado su solución y funcionó bastante bien hasta que descubrí algunos errores. Por ejemplo, 'www.navistar.com' no quita la parte' www'. Esta es la corrección 'if (! Url.Host.EndsWith (". "+ Tld, StringComparison.InvariantCultureIgnoreCase)) continue;' – wpfwannabe

1

Uso Nager.PublicSuffix

instalar paquete 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"; 
Cuestiones relacionadas