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
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.uk
ist 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! -).
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.
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?
Verwenden von python tld
https://pypi.python.org/pypi/tld
pip install tld
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
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=''
# )
from tld import get_fld
get_fld("http://www.google.co.uk")
# 'google.co.uk'
Es gibt viele, viele TLDs. Hier ist die Liste:
http://data.iana.org/TLD/tlds-alpha-by-domain.txt
Hier ist eine andere Liste
http://en.wikipedia.org/wiki/List_of_Internet_top-level_domains
Hier ist eine andere Liste
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
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)