سؤال

يبدو الحصول على النطاق الفرعي من عنوان URL أمرًا سهلاً في البداية.

http://www.domain.example

قم بمسح الفترة الأولى ثم قم بإرجاع ما جاء بعد "http://" ...

ثم تتذكر

http://super.duper.domain.example

أوه.وبعدين تفكر، طيب، ابحث عن الفترة الأخيرة، ارجع كلمة واحدة واحصل على كل شيء قبله!

ثم تتذكر

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

وها أنت تعود إلى المربع الأول.هل لدى أي شخص أي أفكار رائعة إلى جانب تخزين قائمة بجميع نطاقات TLD؟

هل كانت مفيدة؟

المحلول

أي شخص لديه أي أفكار عظيمة إلى جانب تخزين قائمة بجميع نطاقات TLD؟

لا، لأن كل TLD يختلف فيما يمكن اعتباره نطاقًا فرعيًا، أو نطاق المستوى الثاني، وما إلى ذلك.

ضع في اعتبارك أن هناك نطاقات المستوى الأعلى، ونطاقات المستوى الثاني، ونطاقات فرعية.من الناحية الفنية، كل شيء باستثناء TLD هو نطاق فرعي.

في مثال domain.com.uk، "domain" هو نطاق فرعي، و"com" هو نطاق المستوى الثاني، و"uk" هو TLD.

لذلك يظل السؤال أكثر تعقيدًا مما كان عليه في البداية، ويعتمد على كيفية إدارة كل TLD.ستحتاج إلى قاعدة بيانات لجميع نطاقات TLD التي تتضمن التقسيم الخاص بها، وما يعتبر نطاقًا من المستوى الثاني ونطاقًا فرعيًا.ومع ذلك، لا يوجد عدد كبير جدًا من نطاقات TLD، وبالتالي يمكن التحكم في القائمة بشكل معقول، ولكن جمع كل هذه المعلومات ليس بالأمر الهين.قد تكون هناك بالفعل مثل هذه القائمة متاحة.

يشبه http://publicsuffix.org/ هي إحدى هذه القائمة — جميع اللواحق الشائعة (.com، .co.uk، وما إلى ذلك) في قائمة مناسبة للبحث.لن يكون من السهل تحليلها، لكن على الأقل لن يتعين عليك الاحتفاظ بالقائمة.

"اللاحقة العامة" هي التي بموجبها يمكن لمستخدمي الإنترنت التسجيل مباشرة اسماء.بعض الأمثلة على الجمهور اللواحق هي ".com" و ".co.uk" و "pvt.k12.wy.us".اللاحقة العامة القائمة هي قائمة بجميع الأماكن العامة المعروفة اللواحق.

قائمة اللاحقة العامة هي مبادرة من مؤسسة موزيلا.وهي متاحة للاستخدام في أي البرنامج ، ولكن تم إنشاؤه في الأصل لتلبية احتياجات المتصفح المصنعين.يسمح للمتصفحات ، على سبيل المثال:

  • تجنب تعيين "ملفات تعريف الارتباط الفائقة" الضارة بالخصوصية لواحق اسم النطاق عالي المستوى
  • تسليط الضوء على الجزء الأكثر أهمية من اسم المجال في المستخدم واجهه
  • فرز إدخالات السجل بدقة حسب الموقع

أبحث من خلال القائمة, ، يمكنك أن ترى أنها ليست مشكلة تافهة.أعتقد أن القائمة هي الطريقة الصحيحة الوحيدة لتحقيق ذلك ...

نصائح أخرى

وكما يقول آدم، انها ليست سهلة، وحاليا السبيل العملي الوحيد هو استخدام القائمة.

وحتى ذلك الحين هناك استثناءات - على سبيل المثال في .uk هناك عدد قليل من المجالات التي هي صالحة على الفور على هذا المستوى ليست في .co.uk، حتى تلك التي يجب أن تضاف كما الاستثناءات

.

وهذا هو حاليا كيف المتصفحات التيار قيام بذلك - من الضروري ضمان example.co.uk لا يمكن تعيين ملف تعريف الارتباط ل.co.uk التي من شأنها ثم يتم إرسالها إلى أي موقع آخر تحت .co.uk

والخبر السار هو أن هناك بالفعل قائمة متوفرة في http://publicsuffix.org/ .

وهناك أيضا بعض الأعمال في IETF لخلق نوع من معيار للسماح للنطاقات العليا أن تعلن ما يبدو بنية المجال من مثل. هذا معقد قليلا على الرغم من أمثال .uk.com والتي تعمل كما لو كانت لاحقة العامة، ولكن لم يتم بيعها من قبل التسجيل .com.

يبدو أن Publicsuffix.org هي الطريقة التي يجب القيام بها.هناك الكثير من التطبيقات المتاحة لتحليل محتويات ملف بيانات publicsuffix بسهولة:

وكما سبق وقال آدم وجون publicsuffix.org هو الطريق الصحيح للذهاب. ولكن، إذا كان لأي سبب لا يمكنك استخدام هذا النهج، وهنا ارشادي على أساس افتراض أن يعمل لمدة 99٪ من جميع المجالات:

وهناك خاصية واحدة الذي يميز (وليس كل شيء، ولكن ما يقرب من جميع) المجالات "حقيقية" من النطاقات الفرعية ونطاقات TLD وهذا هو سجل MX في DNS و. هل يمكن إنشاء خوارزمية الذي يبحث عن هذا: إزالة أجزاء من المضيف واحدا تلو الآخر والاستعلام عن 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

وهنا مثال في بي:

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:

https://github.com/isaksky/url_dom

وعلى سبيل المثال:

(parse "sub1.sub2.domain.co.uk") 
;=> {:public-suffix "co.uk", :domain "domain.co.uk", :rule-used "*.uk"}

لمكتبة C (مع الجيل جدول البيانات في بيثون)، كتبت HTTP: //code.google.com/p/domain-registry-provider/ وهو سريع والمكان على حد سواء كفاءة.

وتستخدم المكتبة ~ 30KB للجداول البيانات و~ 10KB لرمز C. ليس هناك فوق بدء التشغيل حيث يتم إنشاء الجداول في وقت الترجمة. انظر http://code.google.com/p/domain-registry- مقدم / ويكي / DesignDoc للحصول على مزيد من التفاصيل.

لفهم أفضل رمز جيل الجدول (بايثون)، تبدأ هنا: <لأ href = "http://code.google.com/p/domain-registry-provider/source/browse/trunk/src/registry_tables_generator/ registry_tables_generator.py "يختلط =" نوفولو "> http://code.google.com/p/domain-registry-provider/source/browse/trunk/src/registry_tables_generator/registry_tables_generator.py

لفهم أفضل للAPI C، انظر: <لأ href = "http://code.google.com/p/domain-registry-provider/source/browse/trunk/src/domain_registry/domain_registry.h" يختلط = "نوفولو"> http://code.google.com/p/domain-registry-provider/source/browse/trunk/src/domain_registry/domain_registry.h

وانها ليست انها تعمل على وجه الدقة، ولكن هل يمكن ربما تحصل على اجابة مفيدة من خلال محاولة جلب قطعة المجال عن طريق قطعة والتحقق من استجابة، أي جلب '<لأ href = "HTTP: // المملكة المتحدة" يختلط = " نوفولو noreferrer "> HTTP: // المملكة المتحدة '، ثم' http://co.uk ، ثم ' http://domain.co.uk . عندما تحصل على استجابة غير خطأ كنت قد حصلت على نطاق والباقي هو فرعي.

في بعض الأحيان كنت فقط فلدي أنها محاولة :)

وتحرير:

وتوم ليز يشير في التعليقات، التي تم تعيينها بعض المجالات تصل فقط على نطاق فرعي على شبكة الاتصالات العالمية، التي من شأنها أن تعطينا إجابة غير صحيحة في الاختبار أعلاه. نقطة جيدة! ربما أفضل النهج سيكون للتحقق كل جزء مع " HTTP: // شبكة الاتصالات العالمية " وكذلك من "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

ويمكنك استخدام هذه ليب tld.js: جافا سكريبت API للعمل ضد أسماء النطاقات معقدة، النطاقات الفرعية ومحددات .

tldjs.getDomain('mail.google.co.uk');
// -> 'google.co.uk'

إذا كنت تحصل على المجال الجذر في المتصفح. يمكنك استخدام هذا 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;
    }
  }
};

وعن طريق الكوكي هو صعب.

إذا كنت تتطلع إلى استخراج النطاقات الفرعية و/أو النطاقات من قائمة عشوائية من عناوين 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. استخدم regex في قائمة عناوين 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)

وقائمة اللواحق المشتركة (تغيير .com.eg، كوم، وهلم جرا) لتجريد على طول ب http: // ثم سيكون لديك فقط "sub.domain" للعمل مع بدلا من "<أ href ل = "HTTP: //sub.domain.suffix" يختلط = "نوفولو noreferrer"> HTTP: //sub.domain.suffix "، أو على الأقل هذا ما كنت ربما لا

والمشكلة الأكبر هي قائمة اللواحق المحتملة. هناك الكثير، بعد كل شيء.

بعد إلقاء نظرة سريعة على قائمة publicsuffix.org، يبدو أنه يمكنك إجراء تقدير تقريبي معقول عن طريق إزالة الأجزاء الثلاثة الأخيرة (يعني المقطع هنا قسمًا بين نقطتين) من النطاقات التي يتكون فيها الجزء الأخير من حرفين، على افتراض أنه رمز البلد وسيتم تقسيمه بشكل أكبر.إذا كان المقطع الأخير هو "نحن" وكان المقطع من الثاني إلى الأخير يتكون أيضًا من حرفين، فقم بإزالة المقاطع الأربعة الأخيرة.في جميع الحالات الأخرى، قم بإزالة المقطعين الأخيرين.على سبيل المثال:

"example" ليس حرفين، لذا قم بإزالة "domain.example"، واترك "www"

"example" ليس حرفين، لذا قم بإزالة "domain.example"، مع ترك "super.duper"

يتكون "uk" من حرفين (وليس "نحن")، لذا قم بإزالة "domain.co.uk"، مع ترك "super.duper"

يتكون "us" من حرفين وهو "us"، بالإضافة إلى أن "wy" يتكون أيضًا من حرفين، لذا قم بإزالة "pvt.k12.wy.us"، مع ترك "foo".

لاحظ أنه على الرغم من أن هذا ينطبق على جميع الأمثلة التي رأيتها في الردود حتى الآن، إلا أنه يظل مجرد تقدير تقريبي معقول.هذا ليس صحيحًا تمامًا، على الرغم من أنني أظن أنه أقرب ما يمكن أن تحصل عليه دون إنشاء/الحصول على قائمة فعلية لاستخدامها كمرجع.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top