Pregunta

¿Cómo extraerías el nombre de dominio de una URL, excluyendo los subdominios?

Mi intento simplista inicial fue:

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

Esto funciona para http://www.foo.com, pero no http://www.foo.com.au.¿Hay alguna manera de hacer esto correctamente sin utilizar conocimientos especiales sobre TLD (dominios de nivel superior) válidos o códigos de país (porque cambian)?

gracias

¿Fue útil?

Solución

No, no hay manera "intrínseca" de saber que (por ejemplo) zap.co.it es un subdominio (porque el registrador de Italia tiene que vender dominios tales como co.it), mientras que zap.co.uk no es (porque registrador del Reino Unido NO vende dominios tales como co.uk, pero sólo como <=>).

Usted sólo tiene que utilizar una tabla auxiliar (o fuente en línea) para decirle que se comportan de TLD peculiarmente como Reino Unido de y Australia de - no hay manera de adivinar que a partir de la mirada fija en la cadena sin tal conocimiento adicional semántica (de Por supuesto que puede cambiar con el tiempo, pero si usted puede encontrar una buena fuente en línea que fuente también cambiará en consecuencia, es de esperar -.)

Otros consejos

Aquí está un gran módulo de Python alguien escribió para resolver este problema después de ver a esta pregunta: https://github.com/john-kurkowski/tldextract

El módulo mira hacia arriba dominios de primer nivel en el lista de sufijos Pública , mantenido por los voluntarios de Mozilla

Cita:

  

tldextract por el contrario sabe lo que todos los gTLD [ Genérico dominios de nivel superior ]   y ccTLD [ Código de País dominios de nivel superior ] parecen   mirando encima de los que actualmente viven de acuerdo con el sufijo Pública    lista. Por lo tanto, se proporciona una URL, se conoce su subdominio de su dominio, y su   dominio de su código de país.

este archivo href="http://mxr.mozilla.org/mozilla/source/netwerk/dns/src/effective_tld_names.dat?raw=1" de tlds eficaces demás encontrar en la página web de 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)

resultados en:

abcde.co.uk

Te agradecería que si alguien quisiera saber qué partes de lo anterior podría reescribirse de manera más Pythonic. Por ejemplo, tiene que haber una mejor manera de iterar sobre el last_i_elements lista, pero no podía pensar en uno. Asimismo, no sé si ValueError es lo mejor que puede aumentar. Comentarios?

Uso de pitón tld

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

Instalar

pip install tld

obtener el nombre de dominio de nivel superior como cadena de la URL dada

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

co.uk

o sin protocolo

from tld import get_tld

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

co.uk

Obtener el TLD como un objeto

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=''
# )

Obtener el primer nombre de dominio de primer nivel como cadena de la URL dada

from tld import get_fld

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

He aquí cómo lo manejo:

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)

Hasta get_tld se actualiza para todas las otras nuevas, saco el TLD del error. Claro que es mal código, pero funciona.

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

En Python solía usar tlextracto hasta que falló con una URL como www.mybrand.sa.com analizándolo como subdomain='order.mybrand', domain='sa', suffix='com'!!

Finalmente, decidí escribir este método.

NOTA IMPORTANTE:Esto solo funciona con URL que tienen un subdominio.Esto no pretende reemplazar bibliotecas más avanzadas como tlextracto

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:])}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top