Domanda

come estrarre il nome di dominio da un URL, ad esclusione di eventuali sottodomini?

Il mio iniziale semplicistico tentativo è stato:

'.'.join(urlparse.urlparse(url).netloc.split('.')[-2:])

Questo funziona per http://www.foo.com, ma non http://www.foo.com.au.C'è un modo per farlo correttamente senza l'utilizzo di particolari conoscenze sulle valido Tld (Top Level Domains) o i codici di paese (perché cambiare).

grazie

È stato utile?

Soluzione

No, non c'è modo "intrinseca" di sapere che (per esempio) zap.co.it è un sottodominio (perché registrar in Italia NON vendere i domini come co.it) mentre zap.co.uk non è (perché registrar del Regno Unito non vende domini come co.uk, ma solo come <=>).

Non vi resta che utilizzare una tabella ausiliaria (o fonte online) per dirvi che si comportano di TLD particolarmente come il Regno Unito di e Australia di - non c'è modo di divinazione che da solo a fissare la corda senza tale conoscenza in più semantica (di Naturalmente può cambiare alla fine, ma se è possibile trovare una buona fonte online che fonte cambierà di conseguenza, si spera -!).

Altri suggerimenti

Ecco una grande modulo Python qualcuno ha scritto per risolvere questo problema dopo aver visto questa domanda: https://github.com/john-kurkowski/tldextract

Il modulo guarda in alto TLD nel pubblica elenco dei suffissi , mantenuto da volontari Mozilla

Quote:

  

tldextract d'altra parte sa che cosa tutti i gTLD [ Generic Top-Level Domains ]   e ccTLD [ Country Code Top-Level Domains ] assomigliano   cercando su quelle che attualmente vivono secondo la pubblica suffisso   Lista . Quindi, dato un URL, si conosce il suo sottodominio dal suo dominio, e la sua   dominio dal suo codice paese.

questo file dei TLD efficaci , che presente nel sito web di Mozilla :

from __future__ import with_statement
from urlparse import urlparse

# load tlds, ignore comments and empty lines:
with open("effective_tld_names.dat.txt") as tld_file:
    tlds = [line.strip() for line in tld_file if line[0] not in "/\n"]

def get_domain(url, tlds):
    url_elements = urlparse(url)[1].split('.')
    # url_elements = ["abcde","co","uk"]

    for i in range(-len(url_elements), 0):
        last_i_elements = url_elements[i:]
        #    i=-3: ["abcde","co","uk"]
        #    i=-2: ["co","uk"]
        #    i=-1: ["uk"] etc

        candidate = ".".join(last_i_elements) # abcde.co.uk, co.uk, uk
        wildcard_candidate = ".".join(["*"] + last_i_elements[1:]) # *.co.uk, *.uk, *
        exception_candidate = "!" + candidate

        # match tlds: 
        if (exception_candidate in tlds):
            return ".".join(url_elements[i:]) 
        if (candidate in tlds or wildcard_candidate in tlds):
            return ".".join(url_elements[i-1:])
            # returns "abcde.co.uk"

    raise ValueError("Domain not in global list of TLDs")

print get_domain("http://abcde.co.uk", tlds)

Risultati in:

abcde.co.uk

lo apprezzerei se qualcuno me lo faccia sapere quali bit di cui sopra potrebbe essere riscritto in modo più divinatorio. Ad esempio, ci deve essere un modo migliore di iterazione sul last_i_elements lista, ma non riuscivo a pensare a uno. Anche io non so se ValueError è la cosa migliore per aumentare. Commenti?

Utilizzando python tld

https://pypi.python.org/pypi/tld

Installare

pip install tld

Ottenere i TLD nome come stringa dell'URL

from tld import get_tld
print get_tld("http://www.google.co.uk") 

co.regno unito

o senza protocollo

from tld import get_tld

get_tld("www.google.co.uk", fix_protocol=True)

co.regno unito

Ottenere i TLD come un oggetto

from tld import get_tld

res = get_tld("http://some.subdomain.google.co.uk", as_object=True)

res
# 'co.uk'

res.subdomain
# 'some.subdomain'

res.domain
# 'google'

res.tld
# 'co.uk'

res.fld
# 'google.co.uk'

res.parsed_url
# SplitResult(
#     scheme='http',
#     netloc='some.subdomain.google.co.uk',
#     path='',
#     query='',
#     fragment=''
# )

Ottenere il dominio di primo livello nome come stringa dell'URL

from tld import get_fld

get_fld("http://www.google.co.uk")
# 'google.co.uk'

Ecco come mi occupo di esso:

if not url.startswith('http'):
    url = 'http://'+url
website = urlparse.urlparse(url)[1]
domain = ('.').join(website.split('.')[-2:])
match = re.search(r'((www\.)?([A-Z0-9.-]+\.[A-Z]{2,4}))', domain, re.I)
if not match:
    sys.exit(2)
elif not match.group(0):
    sys.exit(2)

Fino get_tld viene aggiornata per tutti i nuovi, tiro il tld dall'errore. Certo è male il codice, ma funziona.

def get_tld():
  try:
    return get_tld(self.content_url)
  except Exception, e:
    re_domain = re.compile("Domain ([^ ]+) didn't match any existing TLD name!");
    matchObj = re_domain.findall(str(e))
    if matchObj:
      for m in matchObj:
        return m
    raise e

In Python Ho usato per usare tldextract fino a quando non è riuscito con un URL come www.mybrand.sa.com parsing come subdomain='order.mybrand', domain='sa', suffix='com' !!

Così alla fine, ho deciso di scrivere questo metodo

NOTA IMPORTANTE: questo funziona solo con gli URL che hanno un sottodominio in loro. Questo non è destinata a sostituire le librerie più avanzate come tldextract

def urlextract(url):
  url_split=url.split(".")
  if len(url_split) <= 2:
      raise Exception("Full url required with subdomain:",url)
  return {'subdomain': url_split[0], 'domain': url_split[1], 'suffix': ".".join(url_split[2:])}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top