C# 仅从URL获取域名?

C# 仅从URL获取域名?,c#,uri,C#,Uri,我正试图从URL字符串中提取域名。我几乎有了它。。。我正在使用URI 我有一根绳子。。我的第一个想法是使用正则表达式,但后来我决定使用URI类 我需要将上面的内容转换为google.com和没有www的google 我做了以下几件事 Uri test = new Uri(referrer); log.Info("Domain part : " + test.Host); 基本上这会返回www.google.com。。。。如果可能的话,我想尝试返回两张表格。。。如前所述 谷歌网站 还有谷歌 U

我正试图从URL字符串中提取域名。我几乎有了它。。。我正在使用URI

我有一根绳子。。我的第一个想法是使用正则表达式,但后来我决定使用URI类

我需要将上面的内容转换为google.com和没有www的google

我做了以下几件事

Uri test = new Uri(referrer);
log.Info("Domain part : " + test.Host);
基本上这会返回www.google.com。。。。如果可能的话,我想尝试返回两张表格。。。如前所述

谷歌网站 还有谷歌


URI是否可以这样做?

是的,可以使用:

Uri.GetLeftPart( UriPartial.Authority )

google.com不保证与www.google.com相同(好吧,在这个例子中,技术上是一样的,但可能不是这样)


也许你真正需要的是删除“顶级”域名和“www”子域名?然后只需
split('.')
并在最后一部分之前完成该部分

我认为您对“域名”的构成存在误解-在常见用法中没有“纯域名”这一概念-如果您想要一致的结果,您需要定义这一概念。
你只想去掉“www”部分吗? 然后有另一个版本剥离顶级域(例如剥离“.com”或“.co.uk”等部分?)
另一个答案提到split(“.”)-如果您想手动排除主机名的特定部分,则需要使用类似的方法,在.NET framework中没有任何东西可以精确地满足您的需求-您需要自己实现这些东西。

由于域名有很多不同,而且您所描述的“纯域名”不存在任何真正的权威列表,所以我在过去只使用了Uri.Host。为了避免www.google.com和google.com显示为两个不同的域,我经常从包含它的所有域中剥离www.com,因为它几乎保证(几乎)指向同一个站点。这真的是唯一一种不会丢失一些数据的简单方法。

@Dewfy:Dewfy的缺陷是,您的方法返回“www.test.co.uk”的“uk”,但这里的域显然是“test.co.uk”

@naivists:缺陷在于您的方法返回“www.beta.microsoft.com”的“beta.microsoft.com”,但此处的域显然是“microsoft.com”

我需要同样的,所以我写了一个类,你可以复制粘贴到你的解决方案。它使用tld的硬编码字符串数组

输出
microsoft.com


输出
microsoft.co.uk

是的,我在这里发布了解决方案:

如果要删除扩展名,只需添加


if(url.indexof(“.”)1){url=url.substring(0,url.indexof(“.”)}

下面的一些代码只提供SLD加gTLD或ccTLD扩展名(注意下面的例外情况)。我不关心DNS

理论如下:

  • 3个令牌下的任何内容保持原样,例如“localhost”、“domain.com”,否则:最后一个令牌必须是gTLD或ccTLD扩展
  • 如果倒数第二个标记的长度小于3或包含在异常列表中,则将其视为扩展的一部分
  • 最后,该令牌之前的令牌被视为SLD。在此之前的任何内容都被视为子域或主机限定符,例如Www
至于代码,short&sweet:

private static string GetDomainName(string url)
{
    string domain = new Uri(url).DnsSafeHost.ToLower();
    var tokens = domain.Split('.');
    if (tokens.Length > 2)
    {
        //Add only second level exceptions to the < 3 rule here
        string[] exceptions = { "info", "firm", "name", "com", "biz", "gen", "ltd", "web", "net", "pro", "org" }; 
        var validTokens = 2 + ((tokens[tokens.Length - 2].Length < 3 || exceptions.Contains(tokens[tokens.Length - 2])) ? 1 : 0);
        domain = string.Join(".", tokens, tokens.Length - validTokens, validTokens);
    }
    return domain;
}
私有静态字符串GetDomainName(字符串url)
{
string domain=新Uri(url).DnsSafeHost.ToLower();
var tokens=domain.Split('.');
如果(tokens.Length>2)
{
//此处仅向<3规则添加第二级例外
字符串[]异常={“信息”、“公司”、“名称”、“com”、“商业”、“gen”、“ltd”、“web”、“net”、“pro”、“org”};
var validTokens=2+((令牌[tokens.Length-2]。长度<3 | |异常。包含(令牌[tokens.Length-2]))?1:0);
domain=string.Join(“.”,tokens,tokens.Length-validTokens,validTokens);
}
返回域;
}

一个明显的例外是,这不会涉及两个字母的域名。因此,如果你足够幸运拥有ab.com,你需要稍微修改代码。对于我们这些凡人来说,这段代码将覆盖几乎所有的gTLD和ccTLD,减去一些非常奇特的代码。

Uri的主机总是返回域(www.google.com),包括一个标签(www)和一个顶级域(com)。但通常你会想提取中间的部分。我就是这么想的

Uri uri;
bool result = Uri.TryCreate(returnUri, UriKind.Absolute, out uri);
if (result == false)
    return false;

//if you are sure it's not "localhost"
string domainParts = uri.Host.Split('.');
string topLevel = domainParts[domainParts.Length - 1]
string hostBody = domainParts[domainParts.Length - 2]
string label = domainParts[domainParts.Length - 3]

但是您确实需要检查domainParts.length,因为通常给定的uri类似于“google.com”。

我尝试了几乎所有的方法,但都没有达到预期的效果。 下面是我从servermanfail调整的方法

tld文件在上可用 我已经从解析它和搜索tld中获取了文件。如果发布了新的tld,只需下载最新的文件

玩得开心

using System;
using System.Collections.Generic;
using System.IO;

namespace SearchWebsite
{
internal class NetDomain
{
    static public string GetDomainFromUrl(string Url)
    {
        return GetDomainFromUrl(new Uri(Url));
    }

    static public string GetDomainFromUrl(string Url, bool Strict)
    {
        return GetDomainFromUrl(new Uri(Url), Strict);
    }

    static public string GetDomainFromUrl(Uri Url)
    {
        return GetDomainFromUrl(Url, false);
    }

    static public string GetDomainFromUrl(Uri Url, bool Strict)
    {
        initializeTLD();
        if (Url == null) return null;
        var dotBits = Url.Host.Split('.');
        if (dotBits.Length == 1) return Url.Host; //eg http://localhost/blah.php = "localhost"
        if (dotBits.Length == 2) return Url.Host; //eg http://blah.co/blah.php = "localhost"
        string bestMatch = "";
        foreach (var tld in DOMAINS)
        {
            if (Url.Host.EndsWith(tld, StringComparison.InvariantCultureIgnoreCase))
            {
                if (tld.Length > bestMatch.Length) bestMatch = tld;
            }
        }
        if (string.IsNullOrEmpty(bestMatch))
            return Url.Host; //eg http://domain.com/blah = "domain.com"

        //add the domain name onto tld
        string[] bestBits = bestMatch.Split('.');
        string[] inputBits = Url.Host.Split('.');
        int getLastBits = bestBits.Length + 1;
        bestMatch = "";
        for (int c = inputBits.Length - getLastBits; c < inputBits.Length; c++)
        {
            if (bestMatch.Length > 0) bestMatch += ".";
            bestMatch += inputBits[c];
        }
        return bestMatch;
    }


    static private void initializeTLD()
    {
        if (DOMAINS.Count > 0) return;

        string line;
        StreamReader reader = File.OpenText("effective_tld_names.dat");
        while ((line = reader.ReadLine()) != null)
        {
            if (!string.IsNullOrEmpty(line) && !line.StartsWith("//"))
            {
                DOMAINS.Add(line);
            }
        }
        reader.Close();
    }


    // This file was taken from https://publicsuffix.org/list/effective_tld_names.dat

    static public List<String> DOMAINS = new List<String>();
}
使用系统;
使用System.Collections.Generic;
使用System.IO;
名称空间搜索网站
{
内部类NetDomain
{
静态公共字符串GetDomainFromUrl(字符串Url)
{
返回GetDomainFromUrl(新Uri(Url));
}
静态公共字符串GetDomainFromUrl(字符串Url,bool-Strict)
{
返回GetDomainFromUrl(新Uri(Url),严格);
}
静态公共字符串GetDomainFromUrl(Uri Url)
{
返回GetDomainFromUrl(Url,false);
}
静态公共字符串GetDomainFromUrl(Uri Url,bool-Strict)
{
initializeTLD();
if(Url==null)返回null;
var dotBits=Url.Host.Split('.');
if(dotBits.Length==1)返回Url.Host;//例如http://localhost/blah.php =“本地主机”
if(dotBits.Length==2)返回Url.Host;//例如http://blah.co/blah.php =“本地主机”
字符串bestMatch=“”;
foreach(域中的变量tld)
{
if(Url.Host.EndsWith(tld、StringComparison.InvariantCultureIgnoreCase))
{
如果(tld.Length>bestMatch.Length)bestMatch=tld;
}
}
if(string.IsNullOrEmpty(bestMatch))
Uri uri;
bool result = Uri.TryCreate(returnUri, UriKind.Absolute, out uri);
if (result == false)
    return false;

//if you are sure it's not "localhost"
string domainParts = uri.Host.Split('.');
string topLevel = domainParts[domainParts.Length - 1]
string hostBody = domainParts[domainParts.Length - 2]
string label = domainParts[domainParts.Length - 3]
string domain = new Uri(HttpContext.Current.Request.Url.AbsoluteUri).GetLeftPart(UriPartial.Authority);
using System;
using System.Collections.Generic;
using System.IO;

namespace SearchWebsite
{
internal class NetDomain
{
    static public string GetDomainFromUrl(string Url)
    {
        return GetDomainFromUrl(new Uri(Url));
    }

    static public string GetDomainFromUrl(string Url, bool Strict)
    {
        return GetDomainFromUrl(new Uri(Url), Strict);
    }

    static public string GetDomainFromUrl(Uri Url)
    {
        return GetDomainFromUrl(Url, false);
    }

    static public string GetDomainFromUrl(Uri Url, bool Strict)
    {
        initializeTLD();
        if (Url == null) return null;
        var dotBits = Url.Host.Split('.');
        if (dotBits.Length == 1) return Url.Host; //eg http://localhost/blah.php = "localhost"
        if (dotBits.Length == 2) return Url.Host; //eg http://blah.co/blah.php = "localhost"
        string bestMatch = "";
        foreach (var tld in DOMAINS)
        {
            if (Url.Host.EndsWith(tld, StringComparison.InvariantCultureIgnoreCase))
            {
                if (tld.Length > bestMatch.Length) bestMatch = tld;
            }
        }
        if (string.IsNullOrEmpty(bestMatch))
            return Url.Host; //eg http://domain.com/blah = "domain.com"

        //add the domain name onto tld
        string[] bestBits = bestMatch.Split('.');
        string[] inputBits = Url.Host.Split('.');
        int getLastBits = bestBits.Length + 1;
        bestMatch = "";
        for (int c = inputBits.Length - getLastBits; c < inputBits.Length; c++)
        {
            if (bestMatch.Length > 0) bestMatch += ".";
            bestMatch += inputBits[c];
        }
        return bestMatch;
    }


    static private void initializeTLD()
    {
        if (DOMAINS.Count > 0) return;

        string line;
        StreamReader reader = File.OpenText("effective_tld_names.dat");
        while ((line = reader.ReadLine()) != null)
        {
            if (!string.IsNullOrEmpty(line) && !line.StartsWith("//"))
            {
                DOMAINS.Add(line);
            }
        }
        reader.Close();
    }


    // This file was taken from https://publicsuffix.org/list/effective_tld_names.dat

    static public List<String> DOMAINS = new List<String>();
}
var domainParser = new DomainParser(new WebTldRuleProvider());

var domainName = domainParser.Get("sub.test.co.uk");
//domainName.Domain = "test";
//domainName.Hostname = "sub.test.co.uk";
//domainName.RegistrableDomain = "test.co.uk";
//domainName.SubDomain = "sub";
//domainName.TLD = "co.uk";
    public string MainDomainFromHost(string host)
    {
        string[] parts = host.Split('.');
        if (parts.Length <= 2)
            return host; // host is probably already a main domain
        if (parts[parts.Length - 1].All(char.IsNumber))
            return host; // host is probably an IPV4 address
        if (parts[parts.Length - 1].Length == 2 && parts[parts.Length - 2].Length == 2)
            return string.Join(".", parts.TakeLast(3)); // this is the case for co.uk, co.in, etc...
        return string.Join(".", parts.TakeLast(2)); // all others, take only the last 2
    }
private static string GetNameFromHost(string host)
{
    if (host.Count(f => f == '.') == 1)
    {
        return host.Split('.')[0];
    }
    else
    {
        var _list = host.Split('.').ToList();
        return _list.ElementAt(_list.Count - 2);
    }
}