cómo obtener el nombre de dominio de la URL

¿Cómo puedo obtener un nombre de dominio de una cadena URL?

Ejemplos:

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

Relacionado:

  • Coincidencia de una dirección web a través de expresiones regulares

Una vez tuve que escribir esa expresión regular para una empresa para la que trabajé. La solución fue esta:

  • Obtenga una lista de todos los ccTLD y gTLD disponibles. Su primera parada debe ser IANA . La lista de Mozilla se ve muy bien a primera vista, pero carece de ac.uk por ejemplo, así que para esto no es realmente utilizable.
  • Únase a la lista como en el siguiente ejemplo. Una advertencia: ¡ ordenar es importante! Si org.uk aparecería después de uk , example.org.uk coincidiría con org en lugar de example .

Ejemplo regex:

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

Esto funcionó muy bien y también coincidió con top-levels extraños y no oficiales como de.com y amigos.

Lo positivo:

  • Muy rápido si la expresión regular está ordenada de manera óptima

La desventaja de esta solución es, por supuesto:

  • Regex manuscrita que debe actualizarse manualmente si los ccTLD cambian o se agregan. ¡Trabajo tedioso!
  • Regex muy grande por lo que no es muy legible.
 /^(?:www\.)?(.*?)\.(?:com|au\.uk|co\.in)$/ 

Extraer el nombre de dominio con precisión puede ser bastante complicado, principalmente porque la extensión de dominio puede contener 2 partes (como .com.au o .co.uk) y el subdominio (el prefijo) puede o no estar allí. Listar todas las extensiones de dominio no es una opción porque hay cientos de estos. EuroDNS.com, por ejemplo, enumera más de 800 extensiones de nombres de dominio.

Por lo tanto, escribí una breve función php que usa ‘parse_url ()’ y algunas observaciones sobre las extensiones de dominio para extraer con precisión los componentes de la URL Y el nombre de dominio. La función es la siguiente:

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

Esta sencilla función funcionará en casi todos los casos. Hay algunas excepciones, pero estas son muy raras.

Para demostrar / probar esta función, puede usar lo siguiente:

 $urls = array('www.test.com', 'test.com', 'cp.test.com' .....); echo "
"; echo ""; echo ""; foreach ($urls as $url) { $info = parse_url_all($url); echo ""; } echo "
URLHostDomainDomain X
".$url."".$info['host']. "".$info['domain']."".$info['domainX']."
";

El resultado será el siguiente para las URL enumeradas:

enter image description here

Como puede ver, el nombre de dominio y el nombre de dominio sin la extensión se extraen consistentemente independientemente de la URL que se presente a la función.

Espero que esto ayude.

No sé de ninguna biblioteca, pero la manipulación de cadenas de nombres de dominio es bastante fácil.

La parte difícil es saber si el nombre está en el segundo o tercer nivel. Para esto necesitará un archivo de datos que mantenga (por ejemplo, para .uk no siempre es el tercer nivel, algunas organizaciones (por ejemplo, bl.uk, jet.uk) existen en el segundo nivel).

La fuente de Firefox de Mozilla tiene un archivo de datos de este tipo, comprueba las licencias de Mozilla para ver si puedes reutilizarlo.

Hay dos maneras

Usando split

Luego solo analiza esa cadena

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

Usando Regex

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

Espero que esto ayude

 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]) 

No se garantiza que este código funcione con todas las URL y no filtra aquellas que son gtwigticalmente correctas pero no válidas, como ‘example.uk’.

Sin embargo, hará el trabajo en la mayoría de los casos.

Básicamente, lo que quieres es:

 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 

Opcional:

 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 

No necesita construir una expresión regular en constante cambio ya que el 99% de los dominios se combinarán correctamente si simplemente observa la segunda parte del nombre:

 (co|com|gov|net|org) 

Si es uno de estos, entonces necesita unir 3 puntos, sino 2. Simple. Ahora, mi magia regex no puede competir con la de otros SO’ers, así que la mejor manera que he encontrado para lograr esto es con algún código, suponiendo que ya te hayas despojado de la ruta:

  my @d=split /\./,$domain; # split the domain part into an array $c=@d; # 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 

Para obtener el nombre, según su pregunta:

  my @d=split /\./,$domain; # split the domain part into an array $c=@d; # 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 

Me gusta este enfoque porque no requiere mantenimiento. A menos que quiera validar que en realidad es un dominio legítimo, pero eso no tiene sentido porque lo más probable es que solo lo use para procesar los archivos de registro y, en primer lugar, un dominio no válido no se abrirá camino allí.

Si desea hacer coincidir subdominios “no oficiales” como bozo.za.net o bozo.au.uk, bozo.msf.ru simplemente agregue (za | au | msf) a la expresión regular.

Me encantaría ver a alguien hacer todo esto usando solo una expresión regular, estoy seguro de que es posible.

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

el uso de esta javascript regex ignora www y el siguiente punto, mientras conserva el dominio intacto. también coincide adecuadamente no www y cc tld

No es posible sin usar una lista de TLD para comparar, ya que existen muchos casos como http://www.db.de/ o http://bbc.co.uk/

Pero incluso con eso, no tendrás éxito en todos los casos debido a SLD como http://big.uk.com/ o http://www.uk.com/

Si necesita una lista completa, puede usar la lista de sufijo público:

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

Siéntase libre de extender mi función para extraer el nombre de dominio, solo. No usará expresiones regulares y es rápido:

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

Necesita una lista de los prefijos y sufijos de dominio que se pueden eliminar. Por ejemplo:

Prefijos:

  • www.

Sufijos:

  • .com
  • .co.in
  • .au.uk

Entonces, si solo tienes una cadena y no una ventana, puedes usar …

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

Cómo utilizar.

 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'); 

Para un cierto propósito, hice esta rápida función de Python ayer. Devuelve el dominio de la URL. Es rápido y no necesita ningún archivo de entrada que enumere cosas. Sin embargo, no pretendo que funcione en todos los casos, pero realmente hace el trabajo que necesitaba para un simple script de minería de textos.

La salida se ve así:

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

Parece funcionar bastante bien.
Sin embargo, debe modificarse para eliminar las extensiones de dominio en el resultado que desee.

Use esto (.) (. *?) (.) Luego simplemente extraiga los puntos inicial y final. Fácil, ¿verdad?

  1. Cómo es esto

    =((?:(?:(?:http)s?:)?\/\/)?(?:(?:[a-zA-Z0-9]+)\.?)*(?:(?:[a-zA-Z0-9]+))\.[a-zA-Z0-9]{2,3}) (es posible que desee agregar “\ /” al final del patrón)

  2. Si su objective es deshacerse de la url pasada como un param, puede agregar el signo igual como la primera marca, como:

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

    y reemplazar con “/”

El objective de este ejemplo es deshacerse de cualquier nombre de dominio independientemente de la forma en que aparezca. (Es decir, para garantizar que los parámetros de la URL no incluyan los nombres de dominio para evitar el ataque xss)

 #!/usr/bin/perl -w use strict; my $url = $ARGV[0]; if($url =~ /([^:]*:\/\/)?([^\/]*\.)*([^\/\.]+)\.[^\/]+/g) { print $3; } 
 /^(?:https?:\/\/)?(?:www\.)?([^\/]+)/i 

Solo por conocimiento:

 'http://api.livreto.co/books'.replace(/^(https?:\/\/)([az]{3}[0-9]?\.)?(\w+)(\.[a-zA-Z]{2,3})(\.[a-zA-Z]{2,3})?.*$/, '$3$4$5'); # returns livreto.co