سؤال

كيف يمكنك استخراج اسم المجال من عنوان URL ، باستثناء أي من النطاقات الفرعية?

بلدي الأولية الساذجة محاولة:

'.'.join(urlparse.urlparse(url).netloc.split('.')[-2:])

هذا يعمل http://www.foo.com, ولكن ليس http://www.foo.com.au.هل هناك طريقة للقيام بذلك بشكل صحيح دون استخدام المعرفة الخاصة صالحة Tld (نطاقات المستوى الأعلى) أو رموز البلد (لأنها تغيير).

شكرا

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

المحلول

لا، لا توجد وسيلة "الجوهرية" مع العلم أن (على سبيل المثال) zap.co.it هو فرعي (لأن المسجل في ايطاليا هل تبيع المجالات مثل co.it)، في حين zap.co.uk <م> ليس (لأن المسجل في المملكة المتحدة لا يبيع المجالات مثل co.uk، ولكن فقط مثل zap.co.uk).

وسيكون لديك فقط لاستخدام جدول مساعد (أو مصدر على الانترنت) لاقول لكم والتي تتصرف TLD وغريب مثل في المملكة المتحدة واستراليا - ليس هناك وسيلة لالتكهن بأن من مجرد التحديق في سلسلة دون هذه المعرفة الدلالي إضافية (من بالطبع يمكن أن تتغير في نهاية المطاف، ولكن إذا كان يمكنك العثور على مصدر جيد على الانترنت هذا المصدر سوف تتغير أيضا وفقا لذلك، واحدة آمال -!).

نصائح أخرى

وهنا وحدة الثعبان كبيرة كتب شخص ما في حل هذه المشكلة بعد رؤية هذا السؤال: https://github.com/john-kurkowski/tldextract

وحدة بالبحث عن النطاقات العليا في العامة قائمة لاحقة ، المشذبة من قبل متطوعين موزيلا

اقتباس:

<اقتباس فقرة>   

وtldextract من ناحية أخرى يعرف كل ما النطاقات [<م> عام نطاقات المستوى الأعلى ]   و ccTLDs [<م> رمز البلد نطاقات المستوى الأعلى ] تبدو   عن طريق البحث عن تلك التي تعيش حاليا وفقا ل لاحقة العامة   قائمة . لذا، ونظرا لURL، فهو يعرف فرعي لها من المجال الخاص به، ولها   المجال من رمز البلد لها.

باستخدام هذا الملف من فعال tlds التي شخص آخر الاطلاع على موزيلا الموقع:

from __future__ import with_statement
from urlparse import urlparse

# load tlds, ignore comments and empty lines:
with open("effective_tld_names.dat.txt") as tld_file:
    tlds = [line.strip() for line in tld_file if line[0] not in "/\n"]

def get_domain(url, tlds):
    url_elements = urlparse(url)[1].split('.')
    # url_elements = ["abcde","co","uk"]

    for i in range(-len(url_elements), 0):
        last_i_elements = url_elements[i:]
        #    i=-3: ["abcde","co","uk"]
        #    i=-2: ["co","uk"]
        #    i=-1: ["uk"] etc

        candidate = ".".join(last_i_elements) # abcde.co.uk, co.uk, uk
        wildcard_candidate = ".".join(["*"] + last_i_elements[1:]) # *.co.uk, *.uk, *
        exception_candidate = "!" + candidate

        # match tlds: 
        if (exception_candidate in tlds):
            return ".".join(url_elements[i:]) 
        if (candidate in tlds or wildcard_candidate in tlds):
            return ".".join(url_elements[i-1:])
            # returns "abcde.co.uk"

    raise ValueError("Domain not in global list of TLDs")

print get_domain("http://abcde.co.uk", tlds)

النتائج في:

abcde.co.uk

سأكون ممتنا لو شخص اسمحوا لي أن أعرف أي بت من فوق يمكن كتابتها في أكثر pythonic الطريق.على سبيل المثال ، يجب أن تكون هناك طريقة أفضل من بالتكرار عبر last_i_elements قائمة ولكن لم أستطع التفكير واحد.أنا أيضا لا أعرف إذا ValueError هو أفضل شيء إلى رفع.التعليقات ؟

باستخدام بيثون tld

https://pypi.python.org/pypi/tld

تثبيت

pip install tld

الحصول على TLD اسم سلسلة من عنوان معين

from tld import get_tld
print get_tld("http://www.google.co.uk") 

co.المملكة المتحدة

أو بدون بروتوكول

from tld import get_tld

get_tld("www.google.co.uk", fix_protocol=True)

co.المملكة المتحدة

الحصول على TLD ككائن

from tld import get_tld

res = get_tld("http://some.subdomain.google.co.uk", as_object=True)

res
# 'co.uk'

res.subdomain
# 'some.subdomain'

res.domain
# 'google'

res.tld
# 'co.uk'

res.fld
# 'google.co.uk'

res.parsed_url
# SplitResult(
#     scheme='http',
#     netloc='some.subdomain.google.co.uk',
#     path='',
#     query='',
#     fragment=''
# )

الحصول على المستوى الأول اسم المجال باعتبارها سلسلة من عنوان معين

from tld import get_fld

get_fld("http://www.google.co.uk")
# 'google.co.uk'

هناك العديد من, العديد من TLD.وهنا القائمة:

http://data.iana.org/TLD/tlds-alpha-by-domain.txt

هنا قائمة أخرى

http://en.wikipedia.org/wiki/List_of_Internet_top-level_domains

هنا قائمة أخرى

http://www.iana.org/domains/root/db/

وهنا كيف لي التعامل معها:

if not url.startswith('http'):
    url = 'http://'+url
website = urlparse.urlparse(url)[1]
domain = ('.').join(website.split('.')[-2:])
match = re.search(r'((www\.)?([A-Z0-9.-]+\.[A-Z]{2,4}))', domain, re.I)
if not match:
    sys.exit(2)
elif not match.group(0):
    sys.exit(2)

وحتى يتم تحديث get_tld لجميع جديدة، وسحب أدني من الخطأ. ومن المؤكد أنها متاحة سيئة لكنه يعمل.

def get_tld():
  try:
    return get_tld(self.content_url)
  except Exception, e:
    re_domain = re.compile("Domain ([^ ]+) didn't match any existing TLD name!");
    matchObj = re_domain.findall(str(e))
    if matchObj:
      for m in matchObj:
        return m
    raise e

في بيثون اعتدت على استخدام tldextract حتى أنه فشل مع رابط مثل www.mybrand.sa.com تحليل أنها subdomain='order.mybrand', domain='sa', suffix='com'!!

وأخيرا قررت أن أكتب هذا الأسلوب

ملاحظة هامة:هذا يعمل فقط مع عناوين url التي فرعي في نفوسهم.هذا ليس من المفترض أن تحل محل أكثر تقدما مثل المكتبات tldextract

def urlextract(url):
  url_split=url.split(".")
  if len(url_split) <= 2:
      raise Exception("Full url required with subdomain:",url)
  return {'subdomain': url_split[0], 'domain': url_split[1], 'suffix': ".".join(url_split[2:])}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top