2009-12-17 12 views
14

Mi chiedo se ci sia un parser o una libreria in java per estrarre il dominio di secondo livello (SLD) in un URL - o in mancanza di un algo o regex per fare lo stesso . Per esempio:Ottieni il dominio di secondo livello di un URL (java)

URI uri = new URI("http://www.mydomain.ltd.uk/blah/some/page.html"); 

String host = uri.getHost(); 

System.out.println(host); 

che stampa:

mydomain.ltd.uk 

Ora quello che vorrei fare è robusto identificare il componente SLD ("ltd.uk"). Qualche idea?

Modifica: Sono idealmente alla ricerca di una soluzione generale, quindi avrei corrispondenza ".uk" in "police.uk", ".co.uk" in "bbc.co.uk" e " .com "in" amazon.com ".

Grazie

+1

La tua domanda non è ben specificata. Ad esempio, in "mydomain.ltd.uk", "uk" è tecnicamente il dominio di primo livello. –

+0

Jonathan ha ragione. Prendi in considerazione il refactoring della tua domanda. –

+0

sì - lo farà, ma umm ... qual è il termine corretto per l'intero "ltd.uk"? –

risposta

14

Non so il tuo scopo, ma il dominio di secondo livello potrebbe non significare molto per te. Probabilmente hai bisogno di trovare public suffix e il dominio subito sotto è quello che stai cercando.

Apache Http Component (HttpClient 4) viene fornito con le classi per gestire questo,

org.apache.http.impl.cookie.PublicSuffixFilter 
org.apache.http.impl.cookie.PublicSuffixListParser 

È necessario scaricare l'elenco suffissi pubblico da qui,

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

+0

yup che farà applausi piacevolmente –

+0

Ho trovato quella lista in precedenza ma non mi sono preoccupato di postarla perché non contiene ltd. UK. Questo farà ancora quello che vuoi? – danben

+0

@danben: si dovrò aggiungere il ltd.uk (che stavo usando solo a titolo di esempio). Fondamentalmente questa soluzione si riduce a utilizzare un elenco e questo sembra abbastanza completo. Ho contrassegnato come corretta questa risposta per includere il parser. –

-1

Se si desidera che il dominio di secondo livello, è possibile dividere la stringa su "". e prendi le ultime due parti. Naturalmente, questo presuppone che tu abbia sempre un dominio di secondo livello che non è specifico per il sito (poiché sembra che sia quello che vuoi).

+0

purtroppo, questo è un problema generale - quindi ho bisogno di corrispondere a .com, .co.uk, .uk (es. Come in police.uk) ecc. –

+0

In tal caso, potresti provare a compilare un hash da questo elenco - https : //wiki.mozilla.org/TLD_List e quindi controlla le ultime due parti per una corrispondenza del dominio di secondo livello, altrimenti prendi l'ultima parte come TLD. – danben

+0

sì, non credo che ci sia una soluzione programmatica al di là della costruzione di una grande lista da abbinare a –

0

Non ho una risposta per il caso specifico - e il commento di Jonathan sottolinea che probabilmente dovresti rifattorizzare la tua domanda.

Ancora, suggerisco di dare un'occhiata alla classe Reference del progetto Restlet. Ha un sacco di metodi utili. E poiché Restlet è Open Source, non dovrai utilizzare l'intera libreria: potresti scaricare l'origine e aggiungere solo quella classe al tuo progetto.

1
  1. l'elenco di cui + la lettura degli aggiornamenti di wikipedia fornisce un elenco TLD corretto al 98%
  2. passando attraverso http://www.iana.org/domains/root/db/ e fare clic su ogni nic e vedere le ultime notizie ti dà l'altro 2% (come .com.aq e .gov.an)
  3. sfortunatamente grandi fornitori di "spazio web gratuito" sono un'altra cosa da prendere in considerazione, ad es. gli innumerevoli domini * .blogspot.com, se scarichi alexa top 100.000 (file csv gratuito) puoi almeno ottenere una buona panoramica del più usato di questi che ti dovrebbe ottenere per una certa percentuale coperta per questi domini (es. confrontando la valutazione di alexa con stumbleupon visualizzazioni di pagina con deliziosi segnalibri) (alexa a volte prende solo il topdomain mentre delizioso davvero md5 ogni URL, quindi 1 alexa -> più deliziosi hash md5
  4. oltre a quello a volte nel caso di twitter, che cosa va dopo il/è anche importante se stai cercando l'unicità di valutare qualcosa

Ecco un elenco di Alexa top 40.000 quando i TLD reali vengono filtrati per darti una sensazione: (il che significa che Alexa NON conta la valutazione per il dominio per il seguente):

bp.blogspot.com --- espn.go.com- --files.wordpress.com --- --- abcnews.go.com disney.go.com --- --- troktiko.blogspot.com en.wordpress.com --- --- api.ning.com abc.go.com---220.181.38.82---213.174.154.20---abclocal.go.com---feedproxy.google.com/~r---forums.wordpress.com---googleblog.blogspot .com --- 1.cnm999.com/user/10008---213.174.143.196---92.42.51.201---googlewebmastercentral.blogspot.com---myespn.go.com---213.174.143.197-- -61.132.221.146---support.wordpress.com---dashboard.wordpress.com---sethgodin.typepad.com---paygo.17zhifu.com/user/10005---go2.wordpress.com-- -1.1.1.1 --- --- movies.go.com home.comcast.net --- --- googlesystem.blogspot.com abcfamily.go.com --- --- 196,1 home.spaces.live.com .237.210 --- kaixin001.com/~record---xhamster.com /user/video---gold-oil-commodity.blogspot.com---journeyplanner.tfl.gov.uk/user/XSLT_TRIP_REQUEST2---206.108.48.238---blog.wordpress.com---67.220.92.21 ---183.101.80.130---211.94.190.80---youtube-global.blogspot.com---uta-net.com/user/phplib---cinema3satu.blogspot.com---119.147.41.16-- -sites.google.com/site/sites---kk.iij4u.or.jp/~dyo---220.181.6.19---toontown.go.com---signup.wordpress.com---thesartorialist. blogspot.com---analytics.blogspot.com---ss.iij4u.or.jp/~ceh2---67.220.92.23---gmailblog.blogspot.com---183.99.121.86---vgorode.ru /user/create---61.132.216.243---217.175.53.72---labnol.blogspot.com---adsense.blogspot.com---subscribe.wordpress.com---fimotro.blogspot.com-- -creators.ning.com---sarkari-naukri.blogspot.com---search.wordpress.com---orange-hiyoko.blogspot.com---cashewmaniakpop.wordpress.com---pixiehollow.go.com ---adwords.blogspot.com---202.53.226.102---lorelle.wordpress.com---homestead.com/~site---multiply.com/user/signout---221.231.148.249--- 183.101.80.77 --- windowsliveintro. spaces.live.com---124.228.254.234---streaming-web.blogspot.com---id.tianya.cn/user/message---familyfun.go.com---tro-ma-ktiko. blogspot.com---about.ning.com---paygo.17zhifu.com/user/10020---tututina.blogspot.com---toolserver.org/~geohack---superjob.ru/user/resume ---ejobs.ro/user/locuri-de-munca---gnula.blogspot.com---alles.or.jp/~uir---chiark.greenend.org.uk/~sgtatham---woork .blogspot.com --- 88.208.32.218---webstreamingmania.blogspot.com---spaces.live.com---youtube.com/user/RayWilliamJohnson---cloob.com/user/login---asstr .org/~ Kristen --- getclicky.com/user/login---guesshermuff.blogspot.com---211.98.70.195---222.73.105.196---pp.iij4u.or.jp/~taakii-- -unsoloclic.blogspot.com---photoshopdisasters.blogspot.com---218.83.161.253---217.16.18.163---217.16.18.207---217.16.28.104---222.73.105.210---youtube.com /user/OldSpice---hubpages.com/user/new---pelisdvdripdd.blogspot.com---95.143.193.60---es.wordpress.com---217.16.18.206---61.147.116.146-- -damncoolpics.blogspot.com --- --- family.go.com 81.176.235.1 62---gutteruncensorednewsr.blogspot.com---terselubung.blogspot.com---faisalardhy.blogspot.com---67.220.92.14---goodreads.com/user/show---116.228.55.34--- profile.typepad.com---kaixin001.com/~truth---linkbuildersassociated.ning.com---nicotto.jp/user/mypage---ritemail.blogspot.com---hyperboleandahalf.blogspot.com-- -carscoop.blogspot.com---tubemogul.com/user/dash---press-gr.blogspot.com---81.176.235.164---soapnet.go.com---208.98.30.69---trelokouneli .blogspot.com --- help.ning.com---id.tianya.cn/user/register---slovari.yandex.ru/~%D0%BA%D0%BD%D0%B8%D0%B3 % D0% B8 --- --- printable-coupons.blogspot.com unic77.blogspot.com --- globaleconomicanalysis.blogspot.com --- --- 183.101.80.68 221.194.33.60 --- doujin-games88.blogspot .com --- magaseek.com/user/SearchProducts---files.posterous.com---wwwnew.splinder.com---kolom-tutorial.blogspot.com---strobist.blogspot.com---67.21 .91.73 --- needanarticle.com/user/activity---forum.moe.gov.om/~moeoman---milasdaydreams.blogspot.com---88.208.17.189---67.220.92.22---115.238. 100.2 11---nonews-news.blogspot.com---testosterona.blog.br---nn.iij4u.or.jp/~has---cs.tut.fi/~jkorpela---youtube.com/ utente/oldspice --- 67.159.53.25---taxalia.blogspot.com---208.98.30.70---filmesporno.blog.br---alles-schallundrauch.blogspot.com---vatera.hu/user/ account---78.140.136.182---us.my.alibaba.com/user/join---stores.homestead.com---pes2008editing.blogspot.com---ocn.ne.jp/~matrix-- -adweek.blogs.com---115.238.55.94---markjaquith.wordpress.com---k3.dion.ne.jp/~dreamlov---38.99.186.222---film.tv.it--- android-developers.blogspot.com---217.218.110.147---kadokado.com/user/login---bollyvideolinks4u.blogspot.com---sookyeong.wordpress.com---87.101.230.11---livecodes. blogspot.com---67.220.91.19---homepage2.nifty.com/bustered---pp.iij4u.or.jp/~manga100---110.173.49.202---erogamescape.dyndns.org/~ap2- --cs.berkeley.edu/~lorch---cakewrecks.blogspot.com---59.106.117.185---119.75.213.61---id.wordpress.com---de.wordpress.com---telefilmdblink .blogspot.com --- --- 61.139.105.138 si moltiplicano.com/user/unirsi --- programseo.blogspot.com---collectivebias.ning.com---bablorub.blogspot.com---thinkexist.com/user/personalAccount---us.my.alibaba.com/ utente/segno --- 66.70.56.90---getsarkari-naukri.blogspot.com---59.106.117.183---productreviewplace.ning.com---support.weebly.com---kaixin001.com/~lucky ---football-russia.blogspot.com---magaseek.com/user/ItemDetail---polprav.blogspot.com---atlasshrugs2000.typepad.com---jpn-manga.blogspot.com---88.208 .32.219 --- google-latlong.blogspot.com---59.106.117.188---erogamescape.ddo.jp/~ap2---218.87.32.245---watchhorrormovies.blogspot.com---sarotiko.blogspot. com---googlewebmastercentral-de.blogspot.com---colmeia.blog.br---us.my.alibaba.com/user/webatm---220.170.79.109---darkville.blogspot.com--- YouTube/202.108.212.211---homepage3.nifty.com/otakarando---94.77.215.37---pitchit.ning.com---59.106.117.186---thestar.blogs.com---1 .254.254.254 --- piratesonline.go.com---animedblink.blogspot.com---137.32.44.152---eurus.dti.ne.jp/~yoneyama---state.la.us--- lastminute.is.it---bangpai.taobao.com/user/groups---csse.monash.edu.au/~jwb---jquery-howto.blogspot.com---sakura.ne.jp/~ moesino---users.skynet.be/mgueury---saitama.lg.jp---portaldasfinancas.gov.pt---bnonline.fi.cr---135.125.60.11---zhuhai.gd.cn- --kuna.net.kw---59.175.213.77---58.218.199.7---multiply.com/user/signin---youtube.com/user/HDstarcraft---blinklist.com/user/join- --us.my.alibaba.com/user/company---jptwitterhelp.blogspot.com---67.220.92.017---88.208.17.51---youtube.com/user/GoogleWebmasterHelp---208.53.156.229- --filmdblink.blogspot.com---blinklist.com/user/signup---3arbtop.blogspot.com---attivissimo.blogspot.com---onlinemovie12.blogspot.com---98.126.189.86--- mytvsource.blogspot.com---blinklist.com/user/login---googlejapan.blogspot.com---76.73.65.166---gutteruncensorednewsb.blogspot.com---issuu.com/user/upload--- 86.51.174.18---88.208.17.120---profile.china.al ibaba.com/user/admin---jntuworldportal.blogspot.com---sz.js.cn---disneymovieclub.go.com---a1.com.mk---dd.iij4u.or.jp/ ~ --- rr.iij4u.or.jp/~plasma---mlmlaunchformula.ning.com---112.78.7.151---blogdelatele.blogspot.com---googlemobile.blogspot.com---78.109 Madonna. 199.240---wsu.edu/~brians---internapoli-city.blogspot.com---hh.iij4u.or.jp/~dmt---kaixin001.com/~house---61.155.11.14-- -youtube.com/user/SHAYTARDS---turbobit.net/user/files---qjy168.com/user/do---hubpages.com/user/finished---upload2.dyndns.org---f32 .aaa.livedoor.jp/--- ~ naruto-spoilers.blogspot.com---205.209.140.195---193.227.20.21---adsenseforfeeds.blogspot.com---group.ameba.jp/user/ Azusa gruppi ---

2

la risposta selezionata è l'approccio migliore. Per quelli di voi che non vogliono codificarlo, ecco come l'ho fatto.

In primo luogo, non capisco né org.apache.http.impl.cookie.PublicSuffixFilter, o c'è un bug in esso.

In sostanza, se si passa a google.com correttamente restituisce False. Se passi su google.com.au restituisce in modo errato true. Il bug è nel codice che applica i pattern, ad esempio * .au.

Ecco il codice correttore sulla base di org.apache.http.impl.cookie.PublicSuffixFilter:

public class TopLevelDomainChecker { 
    private Set<String> exceptions; 
    private Set<String> suffixes; 

    public void setPublicSuffixes(Collection<String> suffixes) { 
     this.suffixes = new HashSet<String>(suffixes); 
    } 
    public void setExceptions(Collection<String> exceptions) { 
     this.exceptions = new HashSet<String>(exceptions); 
    } 

    /** 
    * Checks if the domain is a TLD. 
    * @param domain 
    * @return 
    */ 
    public boolean isTLD(String domain) { 
     if (domain.startsWith(".")) 
      domain = domain.substring(1); 

     // An exception rule takes priority over any other matching rule. 
     // Exceptions are ones that are not a TLD, but would match a pattern rule 
     // e.g. bl.uk is not a TLD, but the rule *.uk means it is. Hence there is an exception rule 
     // stating that bl.uk is not a TLD. 
     if (this.exceptions != null && this.exceptions.contains(domain)) 
      return false; 


     if (this.suffixes == null) 
      return false; 

     if (this.suffixes.contains(domain)) 
      return true; 

     // Try patterns. ie *.jp means that boo.jp is a TLD 
     int nextdot = domain.indexOf('.'); 
     if (nextdot == -1) 
      return false; 
     domain = "*" + domain.substring(nextdot); 
     if (this.suffixes.contains(domain)) 
      return true; 

     return false; 
    } 


    public String extractSLD(String domain) 
    { 
     String last = domain; 
     boolean anySLD = false; 
     do 
     { 
      if (isTLD(domain)) 
      { 
       if (anySLD) 
        return last; 
       else 
        return ""; 
      } 
      anySLD = true; 
      last = domain; 
      int nextDot = domain.indexOf("."); 
      if (nextDot == -1) 
       return ""; 
      domain = domain.substring(nextDot+1); 
     } while (domain.length() > 0); 
     return ""; 
    } 
} 

e il parser. L'ho ribattezzato.

/** 
* Parses the list from <a href="http://publicsuffix.org/">publicsuffix.org 
* Copied from http://svn.apache.org/repos/asf/httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/cookie/PublicSuffixListParser.java 
*/ 
public class TopLevelDomainParser { 
    private static final int MAX_LINE_LEN = 256; 
    private final TopLevelDomainChecker filter; 

    TopLevelDomainParser(TopLevelDomainChecker filter) { 
     this.filter = filter; 
    } 
    public void parse(Reader list) throws IOException { 
     Collection<String> rules = new ArrayList(); 
     Collection<String> exceptions = new ArrayList(); 
     BufferedReader r = new BufferedReader(list); 
     StringBuilder sb = new StringBuilder(256); 
     boolean more = true; 
     while (more) { 
      more = readLine(r, sb); 
      String line = sb.toString(); 
      if (line.length() == 0) continue; 
      if (line.startsWith("//")) continue; //entire lines can also be commented using // 
      if (line.startsWith(".")) line = line.substring(1); // A leading dot is optional 
      // An exclamation mark (!) at the start of a rule marks an exception to a previous wildcard rule 
      boolean isException = line.startsWith("!"); 
      if (isException) line = line.substring(1); 

      if (isException) { 
       exceptions.add(line); 
      } else { 
       rules.add(line); 
      } 
     } 

     filter.setPublicSuffixes(rules); 
     filter.setExceptions(exceptions); 
    } 
    private boolean readLine(Reader r, StringBuilder sb) throws IOException { 
     sb.setLength(0); 
     int b; 
     boolean hitWhitespace = false; 
     while ((b = r.read()) != -1) { 
      char c = (char) b; 
      if (c == '\n') break; 
      // Each line is only read up to the first whitespace 
      if (Character.isWhitespace(c)) hitWhitespace = true; 
      if (!hitWhitespace) sb.append(c); 
      if (sb.length() > MAX_LINE_LEN) throw new IOException("Line too long"); // prevent excess memory usage 
     } 
     return (b != -1); 
    } 
} 

E, infine, come si usa

FileReader fr = new FileReader("effective_tld_names.dat.txt"); 
    TopLevelDomainChecker checker = new TopLevelDomainChecker(); 
    TopLevelDomainParser parser = new TopLevelDomainParser(checker); 
    parser.parse(fr); 
    boolean result; 
    result = checker.isTLD("com"); // true 
    result = checker.isTLD("com.au"); // true 
    result = checker.isTLD("ltd.uk"); // true 
    result = checker.isTLD("google.com"); // false 
    result = checker.isTLD("google.com.au"); // false 
    result = checker.isTLD("metro.tokyo.jp"); // false 
    String sld; 
    sld = checker.extractSLD("com"); // "" 
    sld = checker.extractSLD("com.au"); // "" 
    sld = checker.extractSLD("google.com"); // "google.com" 
    sld = checker.extractSLD("google.com.au"); // "google.com.au" 
    sld = checker.extractSLD("www.google.com.au"); // "google.com.au" 
    sld = checker.extractSLD("www.google.com"); // "google.com" 
    sld = checker.extractSLD("foo.bar.hokkaido.jp"); // "foo.bar.hokkaido.jp" 
    sld = checker.extractSLD("moo.foo.bar.hokkaido.jp"); // "foo.bar.hokkaido.jp" 
10

Dopo aver guardato queste risposte e non essere soddisfatto da loro ho usato la classe com.google.common.net.InternetDomainName per sottrarre le parti pubbliche di un nome di dominio da tutte le parti:

Set<String> nonePublicDomainParts(String uriHost) { 
    InternetDomainName fullDomainName = InternetDomainName.from(uriHost); 
    InternetDomainName publicDomainName = fullDomainName.publicSuffix(); 
    Set<String> nonePublicParts = new HashSet<String>(fullDomainName.parts()); 
    nonePublicParts.removeAll(publicDomainName.parts()); 
    return nonePublicParts; 
} 

Questa classe è in Maven nel guava biblioteca:

<dependency> 
     <groupId>com.google.guava</groupId> 
     <artifactId>guava</artifactId> 
     <version>10.0.1</version> 
     <scope>compile</scope> 
    </dependency> 

Internamente questa classe sta usando una TldPatterns.class che è pacchetto privata e ha l'elenco dei domini di primo livello al forno in esso.

È interessante notare che se si guarda la sorgente delle classi nel link sottostante, viene esplicitamente indicato "police.uk" come nome di dominio privato. Questo è corretto poichè police.uk è un dominio privato controllato dalla polizia; altro criminals.police.uk sarà email che ti chiede per i dati della carta di credito in relazione alle loro indagini in corso in frodi con carta;)

http://code.google.com/p/guava-libraries/source/browse/guava/src/com/google/common/net/TldPatterns.java?spec=svn8c3cc7e67132f8dcaae4bd214736a8ddf6611769&r=8c3cc7e67132f8dcaae4bd214736a8ddf6611769

0

1.

nonePublicDomainParts metodo dal simbo1905 contributo devono essere corretti a causa di TLD che contengono ".", ad esempio "com.ac":

input: "com.abc.com.ac"

output: "abc"

uscita corretta è "com.abc".

Per ottenere SLD è possibile tagliare TLD da un determinato dominio utilizzando il metodo publicSuffix().

2.

Un insieme non deve essere utilizzato a causa di domini che contengono le stesse parti, ad esempio:

input: part1.part2.part1.TLD

output: part1, part2

uscita corretta è: part1, part2, part1 o in modulo part1.part2.part1

Quindi invece di Set<String> utilizzare List<String>.

0
public static String getTopLevelDomain(String uri) { 

InternetDomainName fullDomainName = InternetDomainName.from(uri); 
InternetDomainName publicDomainName = fullDomainName.topPrivateDomain(); 
String topDomain = ""; 

Iterator<String> it = publicDomainName.parts().iterator(); 
while(it.hasNext()){ 
    String part = it.next(); 
    if(!topDomain.isEmpty())topDomain += "."; 
    topDomain += part; 
} 
return topDomain; 
} 

basta dare il dominio, e la u otterrà il dominio di primo livello. scaricare file jar da http://code.google.com/p/guava-libraries/

0

Dnspy è un'altra alternativa più flessibile alla publicsuffix lib.

Problemi correlati