2009-10-05 3 views

ответ

24

Получение имени хоста достаточно легко, используя urlparse:

hostname = urlparse.urlparse("http://www.techcrunch.com/").hostname 

Получение «корневой домен», однако, будет более проблематично, поскольку он не определен в синтаксическом смысле. Какова корневая область «www.theregister.co.uk»? Как насчет сетей, использующих домены по умолчанию? «devbox12» может быть допустимым именем хоста.

Одним из способов обработки этого является использование Public Suffix List, который пытается каталогизировать как реальные домены верхнего уровня (например, .com "," .net "," .org "), так и частные домены, которые являются использовали как TLD (например, «.co.uk» или даже «.github.io»). Вы можете получить доступ к PSL из Python, используя библиотеку publicsuffix2:

import publicsuffix 
import urlparse 

def get_base_domain(url): 
    # This causes an HTTP request; if your script is running more than, 
    # say, once a day, you'd want to cache it yourself. Make sure you 
    # update frequently, though! 
    psl = publicsuffix.fetch() 

    hostname = urlparse.urlparse(url).hostname 

    return publicsuffix.get_public_suffix(hostname, psl) 
+0

Пожалуйста, объясните, как этот код hostname = ".". join (len (имя хоста [-2]) <4 и имя хоста [-3:] или имя хоста [-2:]) работает? Спасибо – Joozty

+0

@Joozty - Отрицательные индексы начинаются с конца, поэтому 'hostname [-2]' означает следующую запись (в этом случае имя хоста разделяется точками). 'foo и bar или baz' работают очень похоже на тройной: если« foo »истинно, верните« bar »; в противном случае верните «baz». Наконец, 'hostname [-3:]' означает последние три части. Все вместе это означает: «Если следующая-последняя часть имени хоста меньше четырех символов, используйте последние три части и присоединяйте их вместе с точками. В противном случае возьмите только последние две части и соедините их вместе». –

+0

По какой-то причине, даже после установки модуля, на Python 3 я получаю 'ImportError: не могу импортировать имя 'get_public_suffix''. Не удалось найти ответ в Интернете или в документации, поэтому просто используйте «tldextract», а это просто работает! Конечно, мне пришлось сначала «sudo pip3 install tldextract». – Nagev

-4

Это работает для моих целей. Я решил, что поделюсь им.

".".join("www.sun.google.com".split(".")[-2:]) 
+3

Как насчет тестирования «www.sun.google.co.uk»? Вы получите «co.uk» вместо «google.co.uk» ... Приветствия! –

+3

Ya, используйте подход Бена Бланка. Не уверен, что я думал (в 2010 году) :-) –

0

______Using Python 3.3 и 2.x ________

Я хотел бы добавить небольшую вещь, чтобы ответить Бен Бланка.

from urllib.parse import quote,unquote,urlparse 
u=unquote(u) #u= URL e.g. http://twitter.co.uk/hello/there 
g=urlparse(u) 
u=g.netloc 

В настоящем время, я только что получил доменное имя от urlparse.

Чтобы удалить субдомены, вам прежде всего необходимо знать, какие домены верхнего уровня, а какие нет. Например. в приведенном выше http://twitter.co.uk - co.uk является TLD, тогда как в http://sub.twitter.com у нас есть только .com, поскольку TLD и sub является субдоменом.

Итак, нам нужно получить файл/список, в котором есть все tlds.

tlds = load_file("tlds.txt") #tlds holds the list of tlds

hostname = u.split(".") 
if len(hostname)>2: 
    if hostname[-2].upper() in tlds: 
     hostname=".".join(hostname[-3:]) 
    else: 
     hostname=".".join(hostname[-2:]) 
else: 
    hostname=".".join(hostname[-2:]) 
5

Общая структура URL:

scheme://netloc/path;parameters?query#fragment

Как TIMTOWTDI Девиз:

Использование urlparse,

>>> from urllib.parse import urlparse # python 3.x 
>>> parsed_uri = urlparse('http://www.stackoverflow.com/questions/41899120/whatever') # returns six components 
>>> domain = '{uri.netloc}/'.format(uri=parsed_uri) 
>>> result = domain.replace('www.', '') # as per your case 
>>> print(result) 
'stackoverflow.com/' 

Использование tldextract,

>>> import tldextract # The module looks up TLDs in the Public Suffix List, mantained by Mozilla volunteers 
>>> tldextract.extract('http://forums.news.cnn.com/') 
ExtractResult(subdomain='forums.news', domain='cnn', suffix='com') 

в вашем случае:

>>> extracted = tldextract.extract('http://www.techcrunch.com/') 
>>> '{}.{}'.format(extracted.domain, extracted.suffix) 
'techcrunch.com' 

tldextract on the other hand knows what all gTLDs [Generic Top-Level Domains] and ccTLDs [Country Code Top-Level Domains] look like by looking up the currently living ones according to the Public Suffix List. So, given a URL, it knows its subdomain from its domain, and its domain from its country code.

Cheerio!:)

2

Следующий сценарий не является совершенным, но может использоваться для отображения/сокращения. Если вам действительно нужно/нужно избегать любых сторонних зависимостей - особенно отдаленно получать и кэшировать некоторые данные tld, я могу предложить вам следующий сценарий, который я использую в своих проектах. Он использует последние две части домена для большинства распространенных расширений домена и оставляет последние три части для отдыха менее известных расширений домена. В худшем случае домен сценарий будет состоять из трех частей вместо двух:

from urlparse import urlparse 

def extract_domain(url): 
    parsed_domain = urlparse(url) 
    domain = parsed_domain.netloc or parsed_domain.path # Just in case, for urls without scheme 
    domain_parts = domain.split('.') 
    if len(domain_parts) > 2: 
     return '.'.join(domain_parts[-(2 if domain_parts[-1] in { 
      'com', 'net', 'org', 'io', 'ly', 'me', 'sh', 'fm', 'us'} else 3):]) 
    return domain 

extract_domain('google.com')   # google.com 
extract_domain('www.google.com')  # google.com 
extract_domain('sub.sub2.google.com') # google.com 
extract_domain('google.co.uk')  # google.co.uk 
extract_domain('sub.google.co.uk') # google.co.uk 
extract_domain('www.google.com')  # google.com 
extract_domain('sub.sub2.voila.fr') # sub2.voila.fr 
0
def get_domain(url): 
    u = urlsplit(url) 
    return u.netloc 

def get_top_domain(url): 
    u""" 
    >>> get_top_domain('http://www.google.com') 
    'google.com' 
    >>> get_top_domain('http://www.sina.com.cn') 
    'sina.com.cn' 
    >>> get_top_domain('http://bbc.co.uk') 
    'bbc.co.uk' 
    >>> get_top_domain('http://mail.cs.buaa.edu.cn') 
    'buaa.edu.cn' 
    """ 
    domain = get_domain(url) 
    domain_parts = domain.split('.') 
    if len(domain_parts) < 2: 
     return domain 
    top_domain_parts = 2 
    # if a domain's last part is 2 letter long, it must be country name 
    if len(domain_parts[-1]) == 2: 
     if domain_parts[-1] in ['uk', 'jp']: 
      if domain_parts[-2] in ['co', 'ac', 'me', 'gov', 'org', 'net']: 
       top_domain_parts = 3 
     else: 
      if domain_parts[-2] in ['com', 'org', 'net', 'edu', 'gov']: 
       top_domain_parts = 3 
    return '.'.join(domain_parts[-top_domain_parts:]) 
Смежные вопросы