URL에서 하위 도메인을 가져옵니다
문제
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 목록에서 하위 도메인 및/또는 도메인을 추출하려는 경우이 파이썬 스크립트가 도움이 될 수 있습니다. 그래도 조심하십시오. 완벽하지 않습니다. 이것은 일반적으로 해결하기가 까다로운 문제이며 기대하는 도메인의 화이트리스트가 있다면 매우 도움이됩니다.
- 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)))
- Regex를 구축하십시오
import re _regex = '' for domain in domains: _regex += r'{}|'.format(domain.replace('.', '\.')) subdomain_regex = r'/([^/]*)\.[^/.]+\.({})/.*$'.format(_regex) domain_regex = r'([^/.]+\.({}))/.*$'.format(_regex)
- 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"를 남겨 두십시오.
이것은 지금까지 응답에서 본 모든 예제에 효과적이지만, 그것은 합리적인 근사치 일뿐입니다. 참조에 사용할 실제 목록을 만들거나 얻지 않고 얻을 가능성이있는만큼 가까이 있다고 생각하지만 완전히 정확하지는 않습니다.