web-dev-qa-db-de.com

So extrahieren Sie den Top-Level-Domain-Namen (TLD) aus der URL

wie würden Sie den Domainnamen aus einer URL ohne Subdomains extrahieren?

Mein anfänglicher simpler Versuch war:

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

Dies funktioniert für http://www.foo.com , aber nicht http://www.foo.com.a . Gibt es eine Möglichkeit, dies richtig zu tun, ohne spezielle Kenntnisse über gültige TLDs (Top Level Domains) oder Ländercodes (da diese sich ändern) zu verwenden?.

vielen Dank

49
hoju

Nein, es gibt keinen "intrinsischen" Weg zu wissen, dass (zB) zap.co.it Eine Subdomain ist (weil Italiens Registrar keine Domains wie co.it Verkauft), während zap.co.ukist nicht (weil der britische Registrar KEINE Domains wie co.uk verkauft, sondern nur zap.co.uk).

Sie müssen lediglich eine Hilfstabelle (oder eine Online-Quelle) verwenden, um zu ermitteln, welche TLDs sich besonders wie die von Großbritannien und Australien verhalten. Es gibt keine Möglichkeit, dies zu erraten, wenn Sie nur auf die Zeichenfolge starren, ohne dass Sie über ein solches semantisches Wissen verfügen (das ist natürlich möglich) ändern sich schließlich, aber wenn Sie eine gute Online-Quelle finden, wird sich diese Quelle auch entsprechend ändern, hofft man! -).

43
Alex Martelli

Hier ist ein großartiges python Modul, das jemand geschrieben hat, um dieses Problem zu lösen, nachdem er diese Frage gesehen hat: https://github.com/john-kurkowski/tldextract

Das Modul sucht nach TLDs in der Public Suffix List , die von Mozilla-Freiwilligen verwaltet werden

Zitat:

tldextract dagegen weiß, was alle gTLDs [ generische Top-Level-Domains ] und ccTLDs [ ) Ländercode Top-Level-Domains ] sehen so aus, als würden Sie die aktuell lebenden Domains anhand der Public Suffix List nachschlagen. Wenn eine URL angegeben wird, kennt sie ihre Subdomain von ihrer Domain und ihre Domain von ihrem Ländercode.

47
Acorn

Verwenden von diese Datei mit effektiven tlds which jemand anderes gefunden auf Mozillas Website:

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)

ergebnisse in:

abcde.co.uk

Ich würde es begrüßen, wenn mir jemand mitteilen würde, welche der oben genannten Teile auf pythonischere Weise umgeschrieben werden könnten. Zum Beispiel muss es eine bessere Möglichkeit geben, das last_i_elements Liste, aber mir fiel keine ein. Ich weiß auch nicht, ob ValueError das Beste ist, was ich erhöhen kann. Bemerkungen?

42
Markus

Verwenden von python tld

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

Installieren

pip install tld

Ermittelt den TLD-Namen als String aus der angegebenen URL

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

co.uk

oder ohne Protokoll

from tld import get_tld

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

co.uk

Holen Sie sich die TLD als Objekt

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

Ruft den Domainnamen der ersten Ebene als Zeichenfolge von der angegebenen URL ab

from tld import get_fld

get_fld("http://www.google.co.uk")
# 'google.co.uk'
26
2
S.Lott

Bis get_tld für alle neuen aktualisiert ist, ziehe ich die tld aus dem Fehler heraus. Sicher ist es schlechter Code, aber es funktioniert.

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
0
Russ Savage

So gehe ich damit um:

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)
0
Ryan Buckley