获得从URL子域在第一次听起来很容易。
http://www.domain.example
扫描第一时间然后再返回后自由随性的“http://” ...
然后,你还记得
http://super.duper.domain.example
哦。 所以,你想,没关系,找到最后期限,回去一个字和前搞定一切!
然后,你还记得
http://super.duper.domain.co.uk
而你又回到了起点。 任何人都有,除了存储所有顶级域名的列表,任何伟大的想法?
获得从URL子域在第一次听起来很容易。
http://www.domain.example
扫描第一时间然后再返回后自由随性的“http://” ...
然后,你还记得
http://super.duper.domain.example
哦。 所以,你想,没关系,找到最后期限,回去一个字和前搞定一切!
然后,你还记得
http://super.duper.domain.co.uk
而你又回到了起点。 任何人都有,除了存储所有顶级域名的列表,任何伟大的想法?
任何人都有,除了存储所有顶级域名的列表,任何伟大的想法?
没有,因为每个TLD对不同的子域名,二级域名等什么罪名
请记住,有顶级域名,二级域名和子域。 从技术上讲,除了TLD一切都是一个子域。
在domain.com.uk例如,“结构域”是一个子域,“COM”是第二级域,和“英国”是TLD。
因此,问题仍然比乍看之下更加复杂,这取决于每个TLD的管理方式。 你需要所有的包括其特定的分区,什么算作第二级域和子域的顶级域名的数据库。 有没有太多的顶级域名,不过,这样的列表是合理的管理,但收集所有的信息是不平凡的。 可能已经有这样的列表中。
看起来像http://publicsuffix.org/是一个这样的列表的所有的共同列表中的后缀(.COM,.co.uk等)适合用于搜索。 它仍然将是不容易解析它,但至少你不必维护该列表。
“公共后缀”是一个在其下的互联网用户可以直接注册的名字。 公共后缀的一些例子是“.COM”,“.co.uk”和‘pvt.k12.wy.us’。 公共后缀列表是所有已知的公共后缀的列表。
公共后缀列表是Mozilla基金会的倡议。 它可用于在任何软件使用,但在最初创建,以满足浏览器制造商的需求。 它允许浏览器,例如:
- 避免隐私破坏“supercookies”被设置为高级别域名后缀
- 突出一个域名的用户界面中最重要的组成部分
- 准确地网站历史条目进行排序
通过列表看 ,你可以看到它不是一个简单的问题。 我觉得一个列表是完成这一任务的唯一正确的道路......
正如亚当说,这并不容易,目前唯一可行的方法是使用一个列表。
即使这样也有例外-例如.uk
有一些立即生效在这一水平不在域中的少数.co.uk
,所以这些必须添加例外。
这是目前浏览器的主流怎么做到这一点-这是必要的,以确保example.co.uk
不能设置cookie为.co.uk
其将被下发到任何其他网站.co.uk
。
好消息是,已经有可用的列表http://publicsuffix.org/ 。
还有一些工作在IETF建立某种标准允许的TLD申报域结构是什么样子。 这是稍微复杂,虽然通过的喜欢.uk.com
,这好像是一个公共后缀操作,但不会被出售.com
注册。
Publicsuffix.org似乎做的方式。 有很多实现在那里解析容易publicsuffix数据文件文件的内容:
正如已经被亚当说,约翰publicsuffix.org是要走的正确途径。 但是,如果因为任何原因,你不能使用这种方法,这里的基础上,对所有领域的99%的工作假设启发式:
有区分(不是全部,但几乎所有的)“真实”的子域名和顶级域名域一个属性,这就是DNS的MX记录。 你可以创建一个搜索此算法:由一个删除主机名的一个的零件和查询DNS,直到找到一个MX记录。 例:
super.duper.domain.co.uk => no MX record, proceed
duper.domain.co.uk => no MX record, proceed
domain.co.uk => MX record found! assume that's the domain
这里是在PHP一个例子:
function getDomainWithMX($url) {
//parse hostname from URL
//http://www.example.co.uk/index.php => www.example.co.uk
$urlParts = parse_url($url);
if ($urlParts === false || empty($urlParts["host"]))
throw new InvalidArgumentException("Malformed URL");
//find first partial name with MX record
$hostnameParts = explode(".", $urlParts["host"]);
do {
$hostname = implode(".", $hostnameParts);
if (checkdnsrr($hostname, "MX")) return $hostname;
} while (array_shift($hostnameParts) !== null);
throw new DomainException("No MX record found");
}
前面已经说了公共后缀列表中只有一个正确解析域名的方式。 对于PHP你可以尝试TLDExtract 。 下面是示例代码:
$extract = new LayerShifter\TLDExtract\Extract();
$result = $extract->parse('super.duper.domain.co.uk');
$result->getSubdomain(); // will return (string) 'super.duper'
$result->getSubdomains(); // will return (array) ['super', 'duper']
$result->getHostname(); // will return (string) 'domain'
$result->getSuffix(); // will return (string) 'co.uk'
基于从publicsuffix.org的信息Clojure中只是写了一个程序如下:
https://github.com/isaksky/url_dom
例如:
(parse "sub1.sub2.domain.co.uk")
;=> {:public-suffix "co.uk", :domain "domain.co.uk", :rule-used "*.uk"}
为一个C库(与Python数据表生成),我写http://code.google.com/p/domain-registry-provider/这是快速和有效的空间。
库使用〜30KB为C代码中的数据表和〜10KB。 没有启动的开销,因为这些表在编译时构建的。 见http://code.google.com/p/domain-registry-provider/wiki/DesignDoc了解更多详情。
为了更好地理解表格生成代码(蟒蛇),从这里开始: http://code.google.com/p/domain-registry-provider/source/browse/trunk/src/registry_tables_generator/registry_tables_generator.py
为了更好地理解C API,请参见: http://code.google.com/p/domain-registry-provider/source/browse/trunk/src/domain_registry/domain_registry.h
它没有工作,那么确切,但你可以通过尝试获取由一块一块域和检查响应,即可能得到一个有用的答案,取“ 的http://英国 ”,然后“ http://co.uk ” ,然后' http://domain.co.uk '。 当你得到一个无差错响应你有域名,剩下的就是子域。
有时候,你只是要试试吧 :)
编辑:
汤姆·利斯指出,在评论中,有些域设置只在www子域,这将使我们在上面的测试不正确的答案。 好点子! 也许最好的办法是请与“各部分HTTP:// WWW ”以及“的http://”,且算一击要么作为域名的那款一击? 现在,我们仍然缺少一些“另类”的安排,如“web.domain.com”,但我还没有碰到那些一会儿之一:)
使用URIBuilder再拿到URIBUilder.host属性将它分成上的阵列“” 你现在有域的阵列拆分出来。
echo tld('http://www.example.co.uk/test?123'); // co.uk
/**
* http://publicsuffix.org/
* http://www.alandix.com/blog/code/public-suffix/
* http://tobyinkster.co.uk/blog/2007/07/19/php-domain-class/
*/
function tld($url_or_domain = null)
{
$domain = $url_or_domain ?: $_SERVER['HTTP_HOST'];
preg_match('/^[a-z]+:\/\//i', $domain) and
$domain = parse_url($domain, PHP_URL_HOST);
$domain = mb_strtolower($domain, 'UTF-8');
if (strpos($domain, '.') === false) return null;
$url = 'http://mxr.mozilla.org/mozilla-central/source/netwerk/dns/effective_tld_names.dat?raw=1';
if (($rules = file($url)) !== false)
{
$rules = array_filter(array_map('trim', $rules));
array_walk($rules, function($v, $k) use(&$rules) {
if (strpos($v, '//') !== false) unset($rules[$k]);
});
$segments = '';
foreach (array_reverse(explode('.', $domain)) as $s)
{
$wildcard = rtrim('*.'.$segments, '.');
$segments = rtrim($s.'.'.$segments, '.');
if (in_array('!'.$segments, $rules))
{
$tld = substr($wildcard, 2);
break;
}
elseif (in_array($wildcard, $rules) or
in_array($segments, $rules))
{
$tld = $segments;
}
}
if (isset($tld)) return $tld;
}
return false;
}
我只写了一个objc库: https://github.com/kejinlu/KKDomain
您可以使用此LIB tld.js:的JavaScript API来对复杂的域名,子域名和URI工作。
tldjs.getDomain('mail.google.co.uk');
// -> 'google.co.uk'
如果您收到在浏览器中根域。 您可以使用此LIB AngusFu /浏览器的根域 。
var KEY = '__rT_dM__' + (+new Date());
var R = new RegExp('(^|;)\\s*' + KEY + '=1');
var Y1970 = (new Date(0)).toUTCString();
module.exports = function getRootDomain() {
var domain = document.domain || location.hostname;
var list = domain.split('.');
var len = list.length;
var temp = '';
var temp2 = '';
while (len--) {
temp = list.slice(len).join('.');
temp2 = KEY + '=1;domain=.' + temp;
// try to set cookie
document.cookie = temp2;
if (R.test(document.cookie)) {
// clear
document.cookie = temp2 + ';expires=' + Y1970;
return temp;
}
}
};
使用Cookie是棘手的。
如果你正在寻找从URL中的任意列表中提取子域和/或域,这个python脚本可能会有所帮助。 不过要小心,它并不完美。 这是一般的解决棘手的问题,如果你有你期待的域的白名单是非常有帮助的。
import requests url = 'https://publicsuffix.org/list/public_suffix_list.dat' page = requests.get(url) domains = [] for line in page.text.splitlines(): if line.startswith('//'): continue else: domain = line.strip() if domain: domains.append(domain) domains = [d[2:] if d.startswith('*.') else d for d in domains] print('found {} domains'.format(len(domains)))
import re _regex = '' for domain in domains: _regex += r'{}|'.format(domain.replace('.', '\.')) subdomain_regex = r'/([^/]*)\.[^/.]+\.({})/.*$'.format(_regex) domain_regex = r'([^/.]+\.({}))/.*$'.format(_regex)
FILE_NAME = '' # put CSV file name here URL_COLNAME = '' # put URL column name here import pandas as pd df = pd.read_csv(FILE_NAME) urls = df[URL_COLNAME].astype(str) + '/' # note: adding / as a hack to help regex df['sub_domain_extracted'] = urls.str.extract(pat=subdomain_regex, expand=True)[0] df['domain_extracted'] = urls.str.extract(pat=domain_regex, expand=True)[0] df.to_csv('extracted_domains.csv', index=False)
常见的后缀(.co.uk,.COM,等等)的列表,以剔除与HTTP一起://然后你只有“sub.domain”以代替“工作的http://子。 domain.suffix ”,或者至少这就是我可能会做的。
最大的问题是可能的后缀列表。 有很多的,毕竟。
已经采取了快速浏览一下publicsuffix.org名单,看来,你可以通过删除最后三段作出合理的近似(“段”这里指两个点之间的区间),从那里最后的段长两个字符域,假设它是一个国家或地区代码,将进一步细分。 如果最终段是“我们”和第二到最后一段也是两个字符,去掉最后四个部分。 在其他情况下,除去最后两段。 例如:
“实施例”不是两个字符,所以删除“domain.example”,留下“WWW”
“实施例”不是两个字符,所以删除“domain.example”,留下“super.duper”
“英国”是两个字符(而不是“我们”),因此将其删除“domain.co.uk”,留下“super.duper”
“我们”是两个字符,是“我们”,再加上“WY”也是两个字符,所以删除“pvt.k12.wy.us”,让“富”。
需要注意的是,虽然这个工程的,我在答复到目前为止看到的所有例子,但它仍只是一个合理的近似。 这是不完全正确的,但我怀疑这是关于尽可能靠近你可能得到未做/获得实际列表使用参考。