java - from - Obtener el nombre de dominio de la url dada
java url get protocol (9)
Dado un URL, quiero extraer el nombre de dominio (no debe incluir la parte ''www''). La URL puede contener http / https. Aquí está el código de Java que escribí. Aunque parece funcionar bien, ¿hay algún enfoque mejor o hay algunos casos extremos que podrían fallar?
public static String getDomainName(String url) throws MalformedURLException{
if(!url.startsWith("http") && !url.startsWith("https")){
url = "http://" + url;
}
URL netUrl = new URL(url);
String host = netUrl.getHost();
if(host.startsWith("www")){
host = host.substring("www".length()+1);
}
return host;
}
Entrada: http://google.com/blah
Salida: google.com
Aquí hay una línea corta y simple usando InternetDomainName.topPrivateDomain()
en Guava: InternetDomainName.from(new URL(url).getHost()).topPrivateDomain().toString()
Dado http://www.google.com/blah
, eso te dará google.com
. O, dado http://www.google.co.mx
, le dará google.co.mx
.
Como Sa Qada comentó en otra respuesta en esta publicación , esta pregunta se ha formulado anteriormente: Extraiga el nombre de dominio principal de una url determinada . La mejor respuesta a esa pregunta es de Satya , quien sugiere el nombre de dominio de InternetDomainName.topPrivateDomain() de Guava.topPrivadoDominio InternetDomainName.topPrivateDomain()
public boolean isTopPrivateDomain ()
Indica si este nombre de dominio está compuesto exactamente por un componente de subdominio seguido de un sufijo público. Por ejemplo, devuelve verdadero para google.com y foo.co.uk, pero no para www.google.com o co.uk.
Advertencia: Un resultado verdadero de este método no implica que el dominio esté en el nivel más alto que es direccionable como host, ya que muchos sufijos públicos también son hosts direccionables. Por ejemplo, el dominio bar.uk.com tiene un sufijo público de uk.com, por lo que se devolvería verdadero desde este método. Pero uk.com es en sí mismo un host direccionable.
Este método se puede usar para determinar si un dominio es probablemente el nivel más alto para el que se pueden establecer las cookies, aunque incluso eso depende de las implementaciones de los navegadores individuales de los controles de cookies. Ver RFC 2109 para más detalles.
Poniendo eso junto con URL.getHost()
, que la publicación original ya contiene, te da:
import com.google.common.net.InternetDomainName;
import java.net.URL;
public class DomainNameMain {
public static void main(final String... args) throws Exception {
final String urlString = "http://www.google.com/blah";
final URL url = new URL(urlString);
final String host = url.getHost();
final InternetDomainName name = InternetDomainName.from(host).topPrivateDomain();
System.out.println(urlString);
System.out.println(host);
System.out.println(name);
}
}
Escribí un método (ver a continuación) que extrae el nombre de un dominio de una URL y que utiliza una simple coincidencia de cadenas. Lo que realmente hace es extraer el bit entre el primer "://"
(o el índice 0
si no hay "://"
contenidos) y el primer "/"
posterior (o el índice String.length()
si no hay un posterior "/"
). El restante, que precede a "www(_)*."
el bit está cortado. ¡Estoy seguro de que habrá casos en que esto no sea lo suficientemente bueno, pero debería ser lo suficientemente bueno en la mayoría de los casos!
La publicación anterior de Mike Samuel dice que la clase java.net.URI
podría hacer esto (y era preferible a la clase java.net.URL
) pero encontré problemas con la clase URI
. Notablemente, URI.getHost()
da un valor nulo si la url no incluye el esquema, es decir, el bit "http(s)"
.
/**
* Extracts the domain name from {@code url}
* by means of String manipulation
* rather than using the {@link URI} or {@link URL} class.
*
* @param url is non-null.
* @return the domain name within {@code url}.
*/
public String getUrlDomainName(String url) {
String domainName = new String(url);
int index = domainName.indexOf("://");
if (index != -1) {
// keep everything after the "://"
domainName = domainName.substring(index + 3);
}
index = domainName.indexOf(''/'');
if (index != -1) {
// keep everything before the ''/''
domainName = domainName.substring(0, index);
}
// check for and remove a preceding ''www''
// followed by any sequence of characters (non-greedy)
// followed by a ''.''
// from the beginning of the string
domainName = domainName.replaceFirst("^www.*?//.", "");
return domainName;
}
Hay una pregunta similar. Extraiga el nombre de dominio principal de una URL determinada . Si echas un vistazo a esta answer , verás que es muy fácil. Solo necesita usar java.net.URL
y String
utilidad String
- Split
Hice un pequeño tratamiento después de la creación del objeto URI
if (url.startsWith("http:/")) {
if (!url.contains("http://")) {
url = url.replaceAll("http:/", "http://");
}
} else {
url = "http://" + url;
}
URI uri = new URI(url);
String domain = uri.getHost();
return domain.startsWith("www.") ? domain.substring(4) : domain;
Si la url de entrada es la entrada del usuario. este método proporciona el nombre de host más apropiado. si no se encuentra devuelve la url de entrada.
private String getHostName(String urlInput) {
urlInput = urlInput.toLowerCase();
String hostName=urlInput;
if(!urlInput.equals("")){
if(urlInput.startsWith("http") || urlInput.startsWith("https")){
try{
URL netUrl = new URL(urlInput);
String host= netUrl.getHost();
if(host.startsWith("www")){
hostName = host.substring("www".length()+1);
}else{
hostName=host;
}
}catch (MalformedURLException e){
hostName=urlInput;
}
}else if(urlInput.startsWith("www")){
hostName=urlInput.substring("www".length()+1);
}
return hostName;
}else{
return "";
}
}
Si quiere analizar una URL, use java.net.URI
. java.net.URL
tiene un montón de problemas: su método equals
hace una búsqueda de DNS, lo que significa que el código que lo usa puede ser vulnerable a los ataques de denegación de servicio cuando se usa con entradas que no son de confianza.
"Señor Gosling, ¿por qué hizo que la url equivaliera a chupar?" explica uno de esos problemas. Simplemente hágase el hábito de usar java.net.URI
lugar.
public static String getDomainName(String url) throws URISyntaxException {
URI uri = new URI(url);
String domain = uri.getHost();
return domain.startsWith("www.") ? domain.substring(4) : domain;
}
debería hacer lo que quieras
Aunque parece funcionar bien, ¿hay algún enfoque mejor o hay algunos casos extremos que podrían fallar?
Su código como está escrito falla para las URL válidas:
-
httpfoo/bar
: URL relativa con un componente de ruta que comienza conhttp
. -
HTTP://example.com/
- el protocolo no distingue entre mayúsculas y minúsculas. -
//example.com/
- URL relativa del protocolo con un host -
www/foo
: una URL relativa con un componente de ruta que comienza conwww
-
wwwexample.com
- nombre de dominio que no comienza conwww.
pero comienza conwww
.
Las URL jerárquicas tienen una gramática compleja. Si intentas rodar tu propio analizador sintáctico sin leer detenidamente RFC 3986, probablemente te equivocarás. Simplemente use el que está integrado en las bibliotecas centrales.
Si realmente necesita lidiar con entradas desordenadas que java.net.URI
rechaza, vea el Apéndice B de RFC 3986 :
Apéndice B. Analizar una referencia de URI con una expresión regular
Como el algoritmo de "primer partido gana" es idéntico al método de desambiguación "codicioso" utilizado por las expresiones regulares de POSIX, es natural y común usar una expresión regular para analizar los cinco componentes potenciales de una referencia de URI.
La siguiente línea es la expresión regular para desglosar una referencia de URI bien formada en sus componentes.
^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(/?([^#]*))?(#(.*))? 12 3 4 5 6 7 8 9
Los números en la segunda línea de arriba son solo para ayudar a la legibilidad; indican los puntos de referencia para cada subexpresión (es decir, cada paréntesis emparejado).
prueba este: java.net.URL;
JOptionPane.showMessageDialog (null, getDomainName (nueva URL (" https://en.wikipedia.org/wiki/List_of_Internet_top-level_domains ")));
public String getDomainName(URL url){
String strDomain;
String[] strhost = url.getHost().split(Pattern.quote("."));
String[] strTLD = {"com","org","net","int","edu","gov","mil","arpa"};
if(Arrays.asList(strTLD).indexOf(strhost[strhost.length-1])>=0)
strDomain = strhost[strhost.length-2]+"."+strhost[strhost.length-1];
else if(strhost.length>2)
strDomain = strhost[strhost.length-3]+"."+strhost[strhost.length-2]+"."+strhost[strhost.length-1];
else
strDomain = strhost[strhost.length-2]+"."+strhost[strhost.length-1];
return strDomain;}
import java.net.*;
import java.io.*;
public class ParseURL {
public static void main(String[] args) throws Exception {
URL aURL = new URL("http://example.com:80/docs/books/tutorial"
+ "/index.html?name=networking#DOWNLOADING");
System.out.println("protocol = " + aURL.getProtocol()); //http
System.out.println("authority = " + aURL.getAuthority()); //example.com:80
System.out.println("host = " + aURL.getHost()); //example.com
System.out.println("port = " + aURL.getPort()); //80
System.out.println("path = " + aURL.getPath()); // /docs/books/tutorial/index.html
System.out.println("query = " + aURL.getQuery()); //name=networking
System.out.println("filename = " + aURL.getFile()); ///docs/books/tutorial/index.html?name=networking
System.out.println("ref = " + aURL.getRef()); //DOWNLOADING
}
}
private static final String hostExtractorRegexString = "(?:https?://)?(?:www//.)?(.+//.)(com|au//.uk|co//.in|be|in|uk|org//.in|org|net|edu|gov|mil)";
private static final Pattern hostExtractorRegexPattern = Pattern.compile(hostExtractorRegexString);
public static String getDomainName(String url){
if (url == null) return null;
url = url.trim();
Matcher m = hostExtractorRegexPattern.matcher(url);
if(m.find() && m.groupCount() == 2) {
return m.group(1) + m.group(2);
}
else {
return null;
}
}
Explicación: La expresión regular tiene 4 grupos. Los primeros dos son grupos que no coinciden y los dos siguientes son grupos coincidentes.
El primer grupo que no coincide es "http" o "https" o ""
El segundo grupo no coincidente es "www". o ""
El segundo grupo coincidente es el dominio de nivel superior
El primer grupo coincidente es cualquier cosa después de los grupos que no coinciden y cualquier cosa antes del dominio de nivel superior
La concatenación de los dos grupos coincidentes nos dará el dominio / nombre de host.
PD: tenga en cuenta que puede agregar cualquier número de dominios compatibles a la expresión regular.