从URL获取域名?
我正在尝试从URLstring中提取域名。 我几乎拥有它…我正在使用URI
我有一个string..我的第一个想法是使用正则expression式,但后来我决定使用URI类
http://www.google.com/url?sa=t&source=web&ct=res&cd=1&ved=0CAgQFjAA&url=http://www.test.com/&rct=j&q=test&ei=G2phS-HdJJWTjAfckvHJDA&usg=AFQjCNFSEAztaqtkaIvEzxmRm2uOARn1kQ
我需要将以上转换为google.com和谷歌没有www
我做了以下
Uri test = new Uri(referrer); log.Info("Domain part : " + test.Host);
基本上这返回www.google.com ….我想尝试和返回2表格,如果可能的话……如上所述…
google.com和谷歌
这可能与URI?
是的,这是可能的使用:
Uri.GetLeftPart( UriPartial.Authority )
@Dewfy:缺陷是你的方法返回“英国”为“www.test.co.uk”,但这里的域名显然是“test.co.uk”。
@naivists:缺陷是你的方法返回“beta.microsoft.com”为“www.beta.microsoft.com”,但这里的域名显然是“microsoft.com”
我需要相同的,所以我写了一个类,您可以复制并粘贴到您的解决scheme。 它使用一个硬编码的tld的string数组。 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
google.com并不保证与www.google.com相同(对于这个例子来说,它在技术上是,但也可能是)。
也许你需要的是去除“顶级”域和“www”子域? 然后split('.')
并拿到最后一部分之前的部分!
以下是一些仅提供SLD加gTLD或ccTLD扩展的代码(请注意下面的例外情况)。 我不在乎DNS。
理论如下:
- 3令牌下的任何内容都保持原样,例如“localhost”,“domain.com”,否则:最后一个令牌必须是gTLD或ccTLD扩展。
- 倒数第二个标记被认为是扩展的一部分,如果它的长度<3或者包含在例外列表中。
- 最后,那个之前的令牌被认为是SLD。 在此之前的任何事情都被视为一个子域或主机限定符,例如Www。
至于代码,简而言之:
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; }
明显的例外是,这不会处理2个字母的域名。 所以,如果你足够幸运拥有ab.com,你需要稍微修改代码。 对于我们这个凡人来说,这个代码将涵盖几乎所有的通用顶级域名(gTLD)和国家顶级域名(ccTLD),减去一些非常奇特的。
我尝试了几乎所有的方法,但都没有达到预期的效果。 所以这里是我的方法从servermanfail调整。
tld文件在https://publicsuffix.org/list/上可用。我已经从https://publicsuffix.org/list/effective_tld_names.dat中parsing了文件并search了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>(); }
}
我认为你对“域名”的构成有误解 – 通常使用的“纯域名”不存在这种情况 – 如果你想得到一致的结果,你需要定义这个东西。
你只是想剥离“www”部分? 然后有另一个版本剥离顶级域名(例如剥离“.com”或“.co.uk”等部分?)另一个答案提到拆分(“。”) – 您将需要使用的东西像这样,如果你想手动排除主机名的特定部分,.NET框架中没有任何东西可以完全满足你的要求 – 你需要自己实现这些东西。
请参阅Rick Strahl的博客最近作为一些c#和.net为中心的参考:
使ASP.NETpath有意义
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”。
是的,我在这里发布了解决scheme: http : //pastebin.com/raw.php?i=raxNQkCF
如果你想删除扩展只是添加
if (url.indexof(".")>-1) {url = url.substring(0, url.indexof("."))}
由于域名众多的变化,以及您所描述的任何构成“纯域名”的真实权威列表都不存在,所以我刚刚使用过Uri.Host。 为了避免www.google.com和google.com显示为两个不同的域名,我经常采取剥离www。 从包含它的所有域中,因为几乎可以保证(几乎)指向同一个站点。 这是真正做到这一点的唯一简单方法,不会冒丢失一些数据的风险。
string domain = new Uri(HttpContext.Current.Request.Url.AbsoluteUri).GetLeftPart(UriPartial.Authority);