Извлечь доменное имя из URL-адреса в С#

На этот вопрос есть ответ на других языках/платформах, но я не смог найти надежного решения в C#. Здесь я ищу часть URL, которую мы используем в WHOIS, поэтому меня не интересуют поддомены, порт, схема и т. д.

Example 1: http://s1.website.co.uk/folder/querystring?key=value => website.co.uk
Example 2: ftp://username:[email protected] => website.com

Результат должен быть одинаковым, когда владелец в whois один и тот же, поэтому sub1.xyz.com и sub2.xyz.com принадлежат тому, у кого есть xyz.com, который мне нужно извлечь из URL-адреса.


person Xaqron    schedule 08.11.2010    source источник


Ответы (4)


Мне нужно было то же самое, поэтому я написал класс, который вы можете скопировать и вставить в свое решение. Он использует жестко закодированный массив строк tld. http://pastebin.com/raw.php?i=VY3DCNhp

Console.WriteLine(GetDomain.GetDomainFromUrl("http://www.beta.microsoft.com/path/page.htm"));

выходы microsoft.com

и

Console.WriteLine(GetDomain.GetDomainFromUrl("http://www.beta.microsoft.co.uk/path/page.htm"));

выходы microsoft.co.uk

person servermanfail    schedule 13.02.2011
comment
Спасибо, что поделились своей работой. Другая проблема заключается в обновлении списка, но я не думаю, что он меняется очень часто. - person Xaqron; 13.02.2011
comment
Этот класс великолепен. Я составил полный список всех TLD из списка PublicSuffix, обновленный на сегодняшний день. Он почти в два раза больше, чем тот, который вы отправили (~ 6390 записей). Вы можете найти переменную по адресу pastebin.com/raw.php?i=PxKWw5jt, если он вам когда-нибудь понадобится. :) Спасибо еще раз! :) - person moskalak; 02.02.2014
comment
Ни одна из ссылок сейчас недоступна. - person venkat balabhadra; 26.03.2021

Как заметил @Pete, это немного сложно, но я попробую.

Обратите внимание, что эта заявка должна содержать полный список известных TLD. Их можно получить с http://publicsuffix.org/. Оставил извлечение списка с этого сайта в качестве упражнения для читателя.

class Program
{
    static void Main(string[] args)
    {
        var testCases = new[]
        {
            "www.domain.com.ac",
            "www.domain.ac",
            "domain.com.ac",
            "domain.ac",
            "localdomain",
            "localdomain.local"
        };

        foreach (string testCase in testCases)
        {
            Console.WriteLine("{0} => {1}", testCase, UriHelper.GetDomainFromUri(new Uri("http://" + testCase + "/")));
        }

        /* Produces the following results:

            www.domain.com.ac => domain.com.ac
            www.domain.ac => domain.ac
            domain.com.ac => domain.com.ac
            domain.ac => domain.ac
            localdomain => localdomain
            localdomain.local => localdomain.local
         */
    }
}

public static class UriHelper
{
    private static HashSet<string> _tlds;

    static UriHelper()
    {
        _tlds = new HashSet<string>
        {
            "com.ac",
            "edu.ac",
            "gov.ac",
            "net.ac",
            "mil.ac",
            "org.ac",
            "ac"

            // Complete this list from http://publicsuffix.org/.
        };
    }

    public static string GetDomainFromUri(Uri uri)
    {
        return GetDomainFromHostName(uri.Host);
    }

    public static string GetDomainFromHostName(string hostName)
    {
        string[] hostNameParts = hostName.Split('.');

        if (hostNameParts.Length == 1)
            return hostNameParts[0];

        int matchingParts = FindMatchingParts(hostNameParts, 1);

        return GetPartOfHostName(hostNameParts, hostNameParts.Length - matchingParts);
    }

    private static int FindMatchingParts(string[] hostNameParts, int offset)
    {
        if (offset == hostNameParts.Length)
            return hostNameParts.Length;

        string domain = GetPartOfHostName(hostNameParts, offset);

        if (_tlds.Contains(domain.ToLowerInvariant()))
            return (hostNameParts.Length - offset) + 1;

        return FindMatchingParts(hostNameParts, offset + 1);
    }

    private static string GetPartOfHostName(string[] hostNameParts, int offset)
    {
        var sb = new StringBuilder();

        for (int i = offset; i < hostNameParts.Length; i++)
        {
            if (sb.Length > 0)
                sb.Append('.');

            sb.Append(hostNameParts[i]);
        }

        string domain = sb.ToString();
        return domain;
    }
}
person Pieter van Ginkel    schedule 08.11.2010
comment
@Xaqron - я не понимаю, как это сделать. Я скопировал весь код в новый консольный проект, и он правильно компилируется и дает ожидаемые результаты. Не могли бы вы уточнить, чего, по вашему мнению, не хватает? - person Pieter van Ginkel; 08.11.2010
comment
В методе GetDomainFromHostName() отсутствовала шутка, но теперь она есть. Спасибо. - person Xaqron; 08.11.2010

Самое близкое, что вы можете получить, это System.Uri.Host свойство, которое будет извлекать часть sub1.xyz.com. К сожалению, трудно понять, что именно является частью хоста «верхнего уровня» (например, sub1.foo.co.uk или sub1.xyz.com).

person Pete    schedule 08.11.2010
comment
почти невозможно точно знать, какой уровень является верхним, потому что, например, .co.uk требует двух частей, а .info или .jp требуют чего-то другого, кроме .[a-zA-Z]{3} - person jcolebrand; 08.11.2010
comment
Для такого рода задач можно использовать Общедоступный список суффиксов. Но, вероятно, проще всего просто whois ввести все имя хоста и обрабатывать сегмент за раз, пока не получите результаты. - person bobince; 08.11.2010
comment
Этот список должен быть правильным, но это моя точка зрения. должен не является хорошим бизнес-правилом... - person jcolebrand; 08.11.2010
comment
@bobince Да, это, наверное, самый надежный способ сделать это, продвигаясь вверх по сегментам. - person Pete; 08.11.2010

если вам нужно доменное имя, вы можете использовать URi.hostadress в .net

если вам нужен URL-адрес из контента, вам нужно проанализировать их с помощью регулярного выражения.

person Community    schedule 09.11.2010