문제

URL에서 하위 도메인을 얻는 것은 처음에는 쉽게 들립니다.

http://www.domain.example

첫 번째 기간을 스캔 한 다음 "http : //"이후에 온 모든 것을 반환하십시오.

그럼 당신은 기억합니다

http://super.duper.domain.example

오. 그러면 당신은 생각합니다. 좋아요, 마지막 기간을 찾아, 한마디로 돌아가서 전에 모든 것을 얻으십시오!

그럼 당신은 기억합니다

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

그리고 당신은 다시 정사각형으로 돌아 왔습니다. 누구든지 모든 TLD 목록을 저장하는 것 외에 훌륭한 아이디어가 있습니까?

도움이 되었습니까?

해결책

누구든지 모든 TLD 목록을 저장하는 것 외에 훌륭한 아이디어가 있습니까?

아니요, 각 TLD는 하위 도메인, 제 2 레벨 도메인 등으로 간주되는 것과 다르기 때문에.

최상위 도메인, 2 단계 도메인 및 하위 도메인이 있음을 명심하십시오. 기술적으로 말하면, TLD를 제외한 모든 것은 하위 도메인입니다.

Domain.com.uk 예에서 "도메인"은 하위 도메인, "COM"은 두 번째 레벨 도메인이고 "UK"는 TLD입니다.

따라서 문제는 처음 블러쉬보다 더 복잡하며 각 TLD가 관리되는 방식에 따라 다릅니다. 특정 파티셔닝을 포함하는 모든 TLD의 데이터베이스와 두 번째 레벨 도메인 및 하위 도메인으로 간주되는 데이터베이스가 필요합니다. 그러나 TLD가 너무 많지 않으므로 목록은 합리적으로 관리 가능하지만 모든 정보를 수집하는 것은 사소한 일이 아닙니다. 이미 사용 가능한 목록이있을 수 있습니다.

보입니다 http://publicsuffix.org/ 검색에 적합한 목록의 모든 일반적인 접미사 (.com, .co.uk 등)입니다. 여전히 구문 분석하기는 쉽지 않지만 적어도 목록을 유지할 필요는 없습니다.

"공개 접미어"는 인터넷 사용자가 이름을 직접 등록 할 수있는 것입니다. 공개 접미사의 일부 예는 ".com", ".co.uk"및 "pvt.k12.wy.us"입니다. 공개 접미사 목록은 알려진 모든 공개 접미사 목록입니다.

공개 접미사 목록은 Mozilla Foundation의 이니셔티브입니다. 모든 소프트웨어에서 사용할 수 있지만 원래 브라우저 제조업체의 요구를 충족시키기 위해 만들어졌습니다. 예를 들어 브라우저가 다음과 같습니다.

  • 고급 도메인 이름 접미사로 설정중인 개인 정보 보호를 피하십시오.
  • 사용자 인터페이스에서 도메인 이름의 가장 중요한 부분을 강조 표시
  • 현장별로 기록 항목을 정확하게 정렬합니다

목록을 살펴보고 있습니다, 당신은 그것이 사소한 문제가 아니라는 것을 알 수 있습니다. 목록이 이것을 달성하는 유일한 올바른 방법이라고 생각합니다 ...

다른 팁

Adam이 말했듯이 쉽지는 않으며 현재 유일한 실용적인 방법은 목록을 사용하는 것입니다.

그럼에도 불구하고 예외가 있습니다 .uk 해당 레벨에서 즉시 유효한 소수의 도메인이 있습니다. .co.uk, 따라서 예외로 추가해야합니다.

이것은 현재 주류 브라우저 가이 작업을 수행하는 방식입니다. example.co.uk 쿠키를 설정할 수 없습니다 .co.uk 그런 다음 아래의 다른 웹 사이트로 전송됩니다. .co.uk.

좋은 소식은 이미 목록이 있다는 것입니다. http://publicsuffix.org/.

또한 일부 작업이 있습니다 IETF TLD가 도메인 구조의 모습을 선언 할 수 있도록 일종의 표준을 만들려면. 이것은 좋아하지만 약간 복잡합니다 .uk.com, 그것은 마치 공개 접미사 인 것처럼 작동하지만 .com 기재.

publicsuffix.org는 할 수있는 방법입니다. PublicsUffix 데이터 파일의 내용을 쉽게 구문 분석하기위한 많은 구현이 있습니다.

아담과 요한이 이미 말했듯이 publicsuffix.org 올바른 방법입니다. 그러나 어떤 이유로 든이 접근법을 사용할 수 없다면 모든 영역의 99%에 맞는 가정에 근거한 휴리스틱이 있습니다.

하위 도메인 및 TLD와 "실제"도메인을 구별하는 속성이 하나이며 DNS의 MX 레코드입니다. 이를 검색하는 알고리즘을 만들 수 있습니다. 호스트 이름의 부분을 하나씩 제거하고 MX 레코드를 찾을 때까지 DNS를 쿼리하십시오. 예시:

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'

방금 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 자세한 사항은.

테이블 생성 코드 (Python)를 더 잘 이해하려면 여기에서 시작하십시오. 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 : // uk', 그 다음에 'http://co.uk', 그 다음에 'http://domain.co.uk'. 비 방송 응답을 받으면 도메인이 있고 나머지는 하위 도메인입니다.

때때로 당신은 그것을 시도해야합니다 :)

편집하다:

Tom Leys는 의견에서 일부 도메인은 WWW 하위 도메인에만 설정되어 위의 테스트에서 잘못된 답변을 제공 할 것이라고 지적합니다. 좋은 지적! 아마도 가장 좋은 방법은 각 부품을 '로 확인하는 것입니다.http : // www'http : //'뿐만 아니라 도메인 이름의 해당 섹션에 대한 인기로 인기를 얻습니까? 우리는 여전히 'web.domain.com'과 같은 일부 '대체'배열을 놓치고 있지만 한동안 그 중 하나를 만나지 못했습니다 :)

Uribuilder를 사용한 다음 Uribuilder를 가져옵니다. 호스트 속성을 배열로 분할하십시오. " 이제 도메인 분할이있는 배열이 있습니다.

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/Browser-Root-Domain.

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

쿠키를 사용하는 것은 까다 롭습니다.

임의의 URL 목록에서 하위 도메인 및/또는 도메인을 추출하려는 경우이 파이썬 스크립트가 도움이 될 수 있습니다. 그래도 조심하십시오. 완벽하지 않습니다. 이것은 일반적으로 해결하기가 까다로운 문제이며 기대하는 도메인의 화이트리스트가 있다면 매우 도움이됩니다.

  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. Regex를 구축하십시오
import re

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

subdomain_regex = r'/([^/]*)\.[^/.]+\.({})/.*$'.format(_regex)
domain_regex = r'([^/.]+\.({}))/.*$'.format(_regex)
  1. URL 목록에서 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)

http : //와 함께 제거하려면 일반적인 접미사 목록 (.co.uk, .com, et cetera)의 목록은 "sub.domain"만 있으면됩니다.http : //sub.domain.suffix"또는 적어도 그게 내가 할 일입니다.

가장 큰 문제는 가능한 접미사 목록입니다. 결국 많은 것이 있습니다.

PlaxUffix.org 목록을 간단히 살펴보면 최종 세그먼트가 두 문자 길이 인 도메인에서 최종 3 세그먼트 (여기서 두 개의 점 사이의 섹션을 의미)를 제거하여 합리적인 근사치를 만들 수 있습니다. 국가 코드이며 더 세분화 될 것이라고 가정 할 때. 최종 세그먼트가 "US"이고 두 번째로 나오는 세그먼트도 두 문자 인 경우 마지막 4 개의 세그먼트를 제거하십시오. 다른 모든 경우에, 마지막 두 세그먼트를 제거하십시오. 예 :

"예제"는 두 문자가 아니므로 "www"를 남겨두고 "도메인을 제거하십시오"를 제거하십시오.

"예제"는 두 문자가 아니므로 "domain.example"을 제거하여 "super.duper"를 남겨주세요.

"UK"는 두 문자 ( "우리"가 아님)이므로 "domain.co.uk"를 제거하여 "super.duper"를 남겨 둡니다.

"우리"는 두 캐릭터이며 "우리"이며 "Wy"도 두 문자이므로 "pvt.k12.wy.us"를 제거하고 "foo"를 남겨 두십시오.

이것은 지금까지 응답에서 본 모든 예제에 효과적이지만, 그것은 합리적인 근사치 일뿐입니다. 참조에 사용할 실제 목록을 만들거나 얻지 않고 얻을 가능성이있는만큼 가까이 있다고 생각하지만 완전히 정확하지는 않습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top