从URL获取该子域从URL获取该子域(Get the subdomain from a URL)

2019-05-10 11:04发布

获得从URL子域在第一次听起来很容易。

http://www.domain.example

扫描第一时间然后再返回后自由随性的“http://” ...

然后,你还记得

http://super.duper.domain.example

哦。 所以,你想,没关系,找到最后期限,回去一个字和前搞定一切!

然后,你还记得

http://super.duper.domain.co.uk

而你又回到了起点。 任何人都有,除了存储所有顶级域名的列表,任何伟大的想法?

Answer 1:

任何人都有,除了存储所有顶级域名的列表,任何伟大的想法?

没有,因为每个TLD对不同的子域名,二级域名等什么罪名

请记住,有顶级域名,二级域名和子域。 从技术上讲,除了TLD一切都是一个子域。

在domain.com.uk例如,“结构域”是一个子域,“COM”是第二级域,和“英国”是TLD。

因此,问题仍然比乍看之下更加复杂,这取决于每个TLD的管理方式。 你需要所有的包括其特定的分区,什么算作第二级域和子域的顶级域名的数据库。 有没有太多的顶级域名,不过,这样的列表是合理的管理,但收集所有的信息是不平凡的。 可能已经有这样的列表中。

看起来像http://publicsuffix.org/是一个这样的列表的所有的共同列表中的后缀(.COM,.co.uk等)适合用于搜索。 它仍然将是不容易解析它,但至少你不必维护该列表。

“公共后缀”是一个在其下的互联网用户可以直接注册的名字。 公共后缀的一些例子是“.COM”,“.co.uk”和‘pvt.k12.wy.us’。 公共后缀列表是所有已知的公共后缀的列表。

公共后缀列表是Mozilla基金会的倡议。 它可用于在任何软件使用,但在最初创建,以满足浏览器制造商的需求。 它允许浏览器,例如:

  • 避免隐私破坏“supercookies”被设置为高级别域名后缀
  • 突出一个域名的用户界面中最重要的组成部分
  • 准确地网站历史条目进行排序

通过列表看 ,你可以看到它不是一个简单的问题。 我觉得一个列表是完成这一任务的唯一正确的道路......



Answer 2:

正如亚当说,这并不容易,目前唯一可行的方法是使用一个列表。

即使这样也有例外-例如.uk有一些立即生效在这一水平不在域中的少数.co.uk ,所以这些必须添加例外。

这是目前浏览器的主流怎么做到这一点-这是必要的,以确保example.co.uk不能设置cookie为.co.uk其将被下发到任何其他网站.co.uk

好消息是,已经有可用的列表http://publicsuffix.org/ 。

还有一些工作在IETF建立某种标准允许的TLD申报域结构是什么样子。 这是稍微复杂,虽然通过的喜欢.uk.com ,这好像是一个公共后缀操作,但不会被出售.com注册。



Answer 3:

Publicsuffix.org似乎做的方式。 有很多实现在那里解析容易publicsuffix数据文件文件的内容:

  • 的Perl: 域:: PublicSuffix
  • Java的: http://sourceforge.net/projects/publicsuffix/
  • PHP: PHP-域名解析器
  • C#/。NET: https://github.com/danesparza/domainname-parser
  • 的Python: http://pypi.python.org/pypi/publicsuffix
  • 红宝石: domainatrix , public_suffix


Answer 4:

正如已经被亚当说,约翰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");
}


Answer 5:

前面已经说了公共后缀列表中只有一个正确解析域名的方式。 对于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'


Answer 6:

基于从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"}


Answer 7:

为一个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



Answer 8:

它没有工作,那么确切,但你可以通过尝试获取由一块一块域和检查响应,即可能得到一个有用的答案,取“ 的http://英国 ”,然后“ http://co.uk ” ,然后' http://domain.co.uk '。 当你得到一个无差错响应你有域名,剩下的就是子域。

有时候,你只是要试试吧 :)

编辑:

汤姆·利斯指出,在评论中,有些域设置只在www子域,这将使我们在上面的测试不正确的答案。 好点子! 也许最好的办法是请与“各部分HTTP:// WWW ”以及“的http://”,且算一击要么作为域名的那款一击? 现在,我们仍然缺少一些“另类”的安排,如“web.domain.com”,但我还没有碰到那些一会儿之一:)



Answer 9:

使用URIBuilder再拿到URIBUilder.host属性将它分成上的阵列“” 你现在有域的阵列拆分出来。



Answer 10:

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;
}


Answer 11:

我只写了一个objc库: https://github.com/kejinlu/KKDomain



Answer 12:

您可以使用此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是棘手的。



Answer 13:

如果你正在寻找从URL中的任意列表中提取子域和/或域,这个python脚本可能会有所帮助。 不过要小心,它并不完美。 这是一般的解决棘手的问题,如果你有你期待的域的白名单是非常有帮助的。

  1. 得到publicsuffix.org顶级域名
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)))
  1. 建立正则表达式
import re

_regex = ''
for domain in domains:
    _regex += r'{}|'.format(domain.replace('.', '\.'))

subdomain_regex = r'/([^/]*)\.[^/.]+\.({})/.*$'.format(_regex)
domain_regex = r'([^/.]+\.({}))/.*$'.format(_regex)
  1. 在URL列表使用正则表达式
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)


Answer 14:

常见的后缀(.co.uk,.COM,等等)的列表,以剔除与HTTP一起://然后你只有“sub.domain”以代替“工作的http://子。 domain.suffix ”,或者至少这就是我可能会做的。

最大的问题是可能的后缀列表。 有很多的,毕竟。



Answer 15:

已经采取了快速浏览一下publicsuffix.org名单,看来,你可以通过删除最后三段作出合理的近似(“段”这里指两个点之间的区间),从那里最后的段长两个字符域,假设它是一个国家或地区代码,将进一步细分。 如果最终段是“我们”和第二到最后一段也是两个字符,去掉最后四个部分。 在其他情况下,除去最后两段。 例如:

  • HTTP://www.domain.example

“实施例”不是两个字符,所以删除“domain.example”,留下“WWW”

  • HTTP://super.duper.domain.example

“实施例”不是两个字符,所以删除“domain.example”,留下“super.duper”

  • http://super.duper.domain.co.uk

“英国”是两个字符(而不是“我们”),因此将其删除“domain.co.uk”,留下“super.duper”

  • http://foo.pvt.k12.wy.us

“我们”是两个字符,是“我们”,再加上“WY”也是两个字符,所以删除“pvt.k12.wy.us”,让“富”。

需要注意的是,虽然这个工程的,我在答复到目前为止看到的所有例子,但它仍只是一个合理的近似。 这是不完全正确的,但我怀疑这是关于尽可能靠近你可能得到未做/获得实际列表使用参考。



文章来源: Get the subdomain from a URL