Pythonライブラリ tldextract の徹底解説 ✨: URLからドメイン情報を正確に抽出

Python

Web開発やデータ分析に不可欠なURL解析をマスターしよう!

インターネット上の情報はURL (Uniform Resource Locator) によって一意に識別されます。ウェブアプリケーションの開発、データ分析、セキュリティ対策など、様々な場面でURLを解析し、その構成要素(サブドメイン、ドメイン、トップレベルドメイン(TLD)など)を正確に把握する必要が出てきます。

一見すると、URLのドメイン部分は . (ドット) で区切られているため、単純な文字列分割で抽出できそうに思えます。例えば、www.google.com であれば、最後の . で分割すれば com がTLD、その前がドメイン google と考えられます。

しかし、この方法は多くのケースで破綻します。www.bbc.co.uk のような国コードトップレベルドメイン (ccTLD) を含む場合、単純な分割では uk をTLD、co をドメインとして誤認識してしまいます。正しくは co.uk がTLD (正確には Public Suffix)、bbc がドメインです。さらに、pref.kyoto.jp (都道府県型JPドメイン名) や city.shibuya.tokyo.jp のような地域ドメイン、example.blogspot.com のようなサービス提供者がサブドメインをユーザーに提供するケースなど、単純なルールでは対応できないドメイン構造は無数に存在します。

ここで登場するのが Public Suffix List (PSL) です。PSLは、Mozillaが中心となってメンテナンスしている、インターネットユーザーが直接名前を登録できるドメインのサフィックス(接尾辞)の公開リストです。これには .com.org といった一般的なgTLDだけでなく、.co.uk.com.au のようなccTLD、さらにはユーザーが直接登録できるサービスドメイン(例: blogspot.com、これは「プライベートドメイン」と呼ばれることもあります)などが含まれています。

Pythonライブラリ tldextract は、このPSLを利用して、与えられたURLからサブドメイン、ドメイン、そしてPublic Suffix (実効TLDとも呼ばれる) を正確に分離するための強力なツールです。複雑なドメイン構造にも対応し、常に最新のPSLに基づいて解析を行うため、信頼性の高いドメイン情報の抽出が可能になります。🚀

このブログ記事では、tldextract のインストール方法から基本的な使い方、応用的な機能、注意点まで、その魅力を余すところなく徹底的に解説していきます。

tldextract のインストールは、Pythonのパッケージ管理ツールである pip を使って簡単に行えます。ターミナルまたはコマンドプロンプトを開き、以下のコマンドを実行してください。

pip install tldextract

特定のバージョンを指定したい場合や、最新の開発版を試したい場合は、以下のようにします。

# 特定のバージョンを指定 (例: 5.1.3)
pip install tldextract==5.1.3

# 最新の開発版をインストール
pip install -e 'git://github.com/john-kurkowski/tldextract.git#egg=tldextract'

依存ライブラリとして requests, requests-file, filelock, idna などが自動的にインストールされます。

Pythonのバージョン要件: tldextract の最新バージョン (5.x 系) は Python 3.9 以上が必要です。古いPythonバージョンを使用している場合は、互換性のある古いバージョンの tldextract をインストールするか、Python環境をアップグレードする必要があります。

tldextract の最も基本的な機能は、extract 関数を使ってURL文字列からドメイン情報を抽出することです。

import tldextract

# 単純なドメイン
result1 = tldextract.extract('http://www.google.com/search?q=tldextract')
print(f"URL: {result1.fqdn}")
print(f"  Subdomain: {result1.subdomain}")
print(f"  Domain:    {result1.domain}")
print(f"  Suffix:    {result1.suffix}")
print(f"  Registered Domain: {result1.registered_domain}") # domain + suffix
print("-" * 20)

# ccTLDを含むドメイン
result2 = tldextract.extract('https://forums.bbc.co.uk/path/to/page')
print(f"URL: {result2.fqdn}")
print(f"  Subdomain: {result2.subdomain}")
print(f"  Domain:    {result2.domain}")
print(f"  Suffix:    {result2.suffix}")
print(f"  Registered Domain: {result2.registered_domain}")
print("-" * 20)

# サブドメインがない場合
result3 = tldextract.extract('https://example.com')
print(f"URL: {result3.fqdn}")
print(f"  Subdomain: {result3.subdomain}") # 空文字列になる
print(f"  Domain:    {result3.domain}")
print(f"  Suffix:    {result3.suffix}")
print(f"  Registered Domain: {result3.registered_domain}")
print("-" * 20)

# IPアドレスの場合
result4 = tldextract.extract('http://192.168.1.1:8080/admin')
print(f"URL: {result4.fqdn}")
print(f"  Subdomain: {result4.subdomain}") # 空文字列
print(f"  Domain:    {result4.domain}") # IPアドレス全体がドメインとして扱われる
print(f"  Suffix:    {result4.suffix}") # 空文字列
print(f"  Registered Domain: {result4.registered_domain}") # IPアドレス + . (ドットは付かない)
print("-" * 20)

# 無効なサフィックスの場合
result5 = tldextract.extract('http://my.invalid-domain.notatld')
print(f"URL: {result5.fqdn}")
print(f"  Subdomain: {result5.subdomain}")
print(f"  Domain:    {result5.domain}") # サフィックスとして認識できない部分がドメインになる
print(f"  Suffix:    {result5.suffix}") # 空文字列
print(f"  Registered Domain: {result5.registered_domain}") # Domain + Suffix (空)

tldextract.extract() 関数は、ExtractResult というオブジェクトを返します。このオブジェクトは以下の主要な属性を持っています。

  • subdomain: サブドメイン部分 (例: www, forums.news)。存在しない場合は空文字列 ''
  • domain: 登録されているドメイン名部分 (例: google, bbc)。
  • suffix: Public Suffix List に基づくサフィックス部分 (例: com, co.uk)。有効なサフィックスが見つからない場合は空文字列 ''
  • registered_domain: ドメインとサフィックスを結合したもの (例: google.com, bbc.co.uk)。一般的に「ドメイン名」として認識される部分です。
  • fqdn: Fully Qualified Domain Name (完全修飾ドメイン名)。サブドメイン、ドメイン、サフィックスを結合したもの (例: www.google.com, forums.bbc.co.uk)。
  • is_private: 抽出されたサフィックスがPSLのプライベートドメインセクションに含まれるかどうかを示す真偽値 (デフォルトでは考慮されません)。
注意: URLの妥当性検証について
tldextract は、入力された文字列が有効なURL形式であるかどうかを厳密には検証しません。ライブラリの軽量性を保つため、非常に寛容なパースを行います。もし厳密なURL検証が必要な場合は、tldextract を呼び出す前に、urllib.parse や他のバリデーションライブラリを使用してURLの形式をチェックすることが推奨されます。無効なURLや予期しない形式の文字列を入力すると、意図しない結果が返される可能性があります。

tldextract の正確性は、最新の Public Suffix List (PSL) に依存しています。PSLは新しいTLDの追加や既存ルールの変更など、頻繁に更新されます。

tldextract は、このPSLのデータを効率的に扱うためにキャッシュ機構を備えています。初めて tldextract.extract() を呼び出す際、デフォルトではライブHTTPリクエストを発行し、最新のPSLデータをダウンロードしようと試みます。 ダウンロードされたデータは、通常ユーザーのホームディレクトリ以下のキャッシュディレクトリ (例: $HOME/.cache/python-tldextract) にJSONファイルとして保存され、以降の呼び出しではこのキャッシュが利用されます。これにより、毎回ネットワークアクセスを行う必要がなくなり、パフォーマンスが向上します。

このキャッシュは基本的に無期限に保持されます。しかし、PSLは更新されるため、定期的にキャッシュを更新することが重要です。キャッシュの更新は、tldextract.TLDExtract オブジェクトを作成し、その update メソッドを呼び出すか、コマンドラインから tldextract --update を実行することで手動で行えます。

import tldextract

# キャッシュを強制的に更新する
# TLDExtractインスタンスを作成し、update=Trueで呼び出すか、
# updateメソッドを直接呼び出す
extractor = tldextract.TLDExtract()
extractor.update(fetch_now=True) # fetch_now=True で即時更新

print("キャッシュを更新しました。")

# または、extract呼び出し時に update=True を指定
result = tldextract.extract('https://www.google.com', update=True)
print(f"更新後の結果: {result.registered_domain}")
# コマンドラインからキャッシュを更新
tldextract --update
⚠️ 初回実行時の注意点とプロダクション環境での考慮事項
デフォルトの挙動である初回実行時のライブHTTPリクエストは、開発環境では便利ですが、プロダクション環境やネットワーク接続が制限されている環境では問題となる可能性があります。
  • 起動遅延: 初回のリクエストとダウンロードには時間がかかる場合があります。
  • ネットワーク依存: ネットワーク接続がない、またはPSLの配布元サーバーにアクセスできない場合、最新リストの取得に失敗します(ただし、通常は組み込みのスナップショットにフォールバックします)。
  • ファイアウォール: ファイアウォール設定によっては、外部へのHTTPリクエストがブロックされる可能性があります。
  • セキュリティポリシー: アプリケーション実行時に外部へのHTTP通信を許可しないセキュリティポリシーがある場合、問題となります。(2022年頃には、このデフォルト挙動が危険であるとの指摘もありました。)
これらの問題を避けるため、プロダクション環境では以下のいずれかの対策を検討してください。
  1. デプロイ/ビルド時にキャッシュを事前生成する: Dockerfileなどでビルドプロセス中に tldextract --update を実行し、キャッシュファイルをコンテナイメージに含めておく。
  2. キャッシュディレクトリを指定し、管理する: 環境変数 TLDEXTRACT_CACHETLDExtractcache_dir 引数でキャッシュファイルの場所を明示的に指定し、定期的な更新プロセスを別途用意する。
  3. HTTPリクエストを無効にする: TLDExtractsuffix_list_urls=()fallback_to_snapshot=True を指定して、ネットワークアクセスを行わず、ライブラリに同梱されているスナップショットのみを使用する(ただし、このスナップショットはライブラリのバージョンアップ時しか更新されません)。
  4. キャッシュ自体を無効にする: TLDExtract(cache_file=False) または TLDExtract(cache_dir=None) とすることでキャッシュ機能自体を無効化できます。この場合、PSLデータはメモリ上でのみ処理されますが、呼び出しごとにPSLデータのロードが必要になる可能性があります。

キャッシュファイルの場所は、環境変数 TLDEXTRACT_CACHE で指定するか、TLDExtract オブジェクトを初期化する際に cache_dir (または非推奨ですが cache_file) パラメータで指定できます。

import tldextract
import os

# 環境変数でキャッシュディレクトリを指定 (実行前に設定)
# export TLDEXTRACT_CACHE=/path/to/your/cache/dir

# TLDExtract オブジェクトで指定
custom_cache_dir = "/tmp/my_tldextract_cache"
os.makedirs(custom_cache_dir, exist_ok=True)

extractor = tldextract.TLDExtract(cache_dir=custom_cache_dir)
result = extractor("https://www.example.org")
print(f"カスタムキャッシュ使用: {result.registered_domain}")
print(f"キャッシュファイルパス: {extractor.cache_file}")

# キャッシュを無効にする例
no_cache_extractor = tldextract.TLDExtract(cache_dir=None)
result_no_cache = no_cache_extractor("https://www.example.net")
print(f"キャッシュ無効: {result_no_cache.registered_domain}")

また、PSLの取得元URLを独自のものに変更したり、ローカルファイルパスを指定したりすることも可能です。suffix_list_urls 引数にURLまたは file:// スキームのパスを指定します。

import tldextract

# カスタムURLまたはローカルファイルを指定
# (例: 事前にダウンロードしておいたPSLファイル)
local_psl_path = "/path/to/public_suffix_list.dat"
# file:// スキームを使用する場合は絶対パス推奨
file_url = f"file://{os.path.abspath(local_psl_path)}"

# ネットワークアクセスを行わず、ローカルファイルと組み込みスナップショットのみを使用
extractor_local = tldextract.TLDExtract(
    suffix_list_urls=[file_url], # 独自のソースを指定
    fallback_to_snapshot=True # ローカルファイルがなくても組み込みを使う
)
result_local = extractor_local("https://custom.example.local")
print(f"カスタムPSL使用: {result_local.registered_domain}")

# ネットワークアクセスを完全に無効化し、組み込みスナップショットのみを使用
no_fetch_extractor = tldextract.TLDExtract(
    suffix_list_urls=(),
    fallback_to_snapshot=True
)
result_snapshot = no_fetch_extractor("https://snapshot.example.org")
print(f"スナップショットのみ使用: {result_snapshot.registered_domain}")

ヒント: ライブラリをアップグレードした際には、古いキャッシュファイルとの互換性の問題が発生する可能性があるため、キャッシュファイルを一度削除することが推奨されています。
マルチスレッド/マルチプロセス環境での注意: 複数のプロセスやスレッドが同時にキャッシュファイルにアクセスし、更新しようとすると、ファイルロックの競合が発生することがあります (Timeout: The file lock ... could not be acquired エラー)。これを避けるためには、以下のいずれかの方法が考えられます。
  • 各プロセス/スレッドに異なるキャッシュファイルパスを指定する。
  • キャッシュの更新を単一のプロセス/スレッドに限定するか、事前に更新しておく。
  • キャッシュのライブ更新を無効にする (fallback_to_snapshot=True, suffix_list_urls=())。
  • キャッシュ自体を無効にする (cache_dir=None)。

tldextract は基本的な使い方以外にも、いくつかの便利なオプションと機能を提供しています。

プライベートドメインの扱い (include_psl_private_domains)

Public Suffix List には、ICANNが管理する公式なTLD(例: .com, .org, .uk)とは別に、「プライベートドメイン」セクションが含まれています。これらは、特定のサービス提供者(例: blogspot.com, github.io)が、自身のドメインの下でユーザーにサブドメインを提供している場合に、そのサービスドメイン自体をサフィックスとして扱うためのものです。

デフォルトでは、tldextract はこれらのプライベートドメインをサフィックスとして扱いません。これは、多くのユーザーが myblog.blogspot.com のドメイン部分を blogspot と認識する方が一般的であるという考えに基づいています。

しかし、アプリケーションによっては(例えば、クッキーのスコープをブラウザと同様に扱いたい場合など)、これらのプライベートドメインもサフィックスとして扱いたい場合があります。その場合は、TLDExtract オブジェクトを初期化する際に include_psl_private_domains=True を指定します。

import tldextract

url = 'https://mycoolpage.github.io'

# デフォルト (プライベートドメインをサフィックスとして扱わない)
extractor_default = tldextract.TLDExtract()
result_default = extractor_default(url)
print("デフォルト:")
print(f"  Subdomain: {result_default.subdomain}") # mycoolpage
print(f"  Domain:    {result_default.domain}")    # github
print(f"  Suffix:    {result_default.suffix}")    # io
print(f"  Is Private: {result_default.is_private}") # False

print("-" * 20)

# プライベートドメインをサフィックスとして扱う
extractor_private = tldextract.TLDExtract(include_psl_private_domains=True)
result_private = extractor_private(url)
print("プライベートドメインを含む場合:")
print(f"  Subdomain: {result_private.subdomain}") # '' (空)
print(f"  Domain:    {result_private.domain}")    # mycoolpage
print(f"  Suffix:    {result_private.suffix}")    # github.io
print(f"  Is Private: {result_private.is_private}") # True

extract 関数に直接指定することも可能です:

result_private_direct = tldextract.extract(url, include_psl_private_domains=True)
print(f"直接指定: Suffix={result_private_direct.suffix}, Is Private={result_private_direct.is_private}")

PSLのプライベートセクションに自分のサフィックスが含まれているのに、tldextract がそれを抽出しない場合は、このオプションを確認してみてください。

カスタムサフィックスの追加 (extra_suffixes)

PSLに含まれていない、あるいはまだ反映されていない独自のサフィックスルールを追加したい場合があるかもしれません。例えば、社内ネットワークでのみ使用される特殊なドメインなどです。TLDExtractextra_suffixes 引数に、追加したいサフィックスのリスト(文字列のシーケンス)を渡すことで、既存のPSLルールにマージして解析を行うことができます。

import tldextract

# 'internal.corp' をカスタムサフィックスとして追加
custom_extractor = tldextract.TLDExtract(
    extra_suffixes=['internal.corp', '.company.local'] # 先頭のドットはあってもなくても良い
)

url1 = 'https://project-a.internal.corp/dashboard'
result1 = custom_extractor(url1)
print(f"URL: {url1}")
print(f"  Subdomain: {result1.subdomain}") # ''
print(f"  Domain:    {result1.domain}")    # project-a
print(f"  Suffix:    {result1.suffix}")    # internal.corp

print("-" * 20)

url2 = 'http://fileserver.dept1.company.local'
result2 = custom_extractor(url2)
print(f"URL: {url2}")
print(f"  Subdomain: {result2.subdomain}") # fileserver.dept1
print(f"  Domain:    {result2.domain}")    # '' (サフィックスのみの場合) - 注意: この挙動は想定と異なる可能性あり。通常は domain='dept1'などを期待するかもしれないが、extra_suffixes のマッチングによる。
print(f"  Suffix:    {result2.suffix}")    # company.local (より長い .company.local がマッチ)
print(f"  Registered Domain: {result2.registered_domain}") # domain + suffix

# extract 関数に直接指定
result_extra_direct = tldextract.extract(url1, extra_suffixes=['internal.corp'])
print(f"直接指定: Suffix={result_extra_direct.suffix}")

もし、特定のドメインに対する例外を追加したい場合(例えば、公式PSLに追加を申請中など)、この機能を使うか、PSLをフォークして独自のリストを作成し suffix_list_urls で指定する方法があります。

コマンドラインインターフェース (CLI)

tldextract はPythonライブラリとしてだけでなく、簡単なコマンドラインツールとしても利用できます。URLを引数として渡すと、サブドメイン、ドメイン、サフィックスをスペース区切りで出力します。

tldextract https://sub.example.co.uk/page
# 出力: sub example co.uk

tldextract my.custom.domain.internal.corp --extra internal.corp
# 出力: my.custom domain internal.corp

tldextract https://myblog.blogspot.com --private
# 出力: myblog blogspot.com '' (Suffixは空になる? -> 確認必要。通常は suffix=blogspot.com)
# --private オプションでプライベートドメインを考慮 (ただしCLIの挙動は要確認)

tldextract --update # キャッシュの更新

tldextract --json https://sub.example.com # JSON形式で出力
# 出力: {"subdomain": "sub", "domain": "example", "suffix": "com", "is_private": false}

簡単な確認やシェルスクリプトでの利用に便利です。JSON出力オプション (-j または --json) も利用可能です (バージョン 5.1.0 以降)。

戻り値オブジェクト ExtractResult の詳細

v5.0.0 以降、tldextract.extract() が返すオブジェクトは、従来の `namedtuple` から `dataclass` に変更されました。これにより、後方互換性のない変更点があります。

  • インデックス/スライスアクセス不可: 以前のように result[0]result[1:] といったアクセスはできなくなりました。必ず属性名 (result.subdomain, result.domain など) を使用する必要があります。
  • アンパック不可: sub, domain, suffix = tldextract.extract(...) のようなアンパックも直接はできません。
import tldextract

result = tldextract.extract('https://sub.example.com')

# 正しいアクセス方法 (v5.0.0以降)
print(result.subdomain)
print(result.domain)
print(result.suffix)

# 以前のバージョンでのみ可能だったアクセス (v5.0.0以降はエラー)
# print(result[0])  # TypeError
# sub, dom, suf = result # TypeError

この変更は、より明確なコードと型ヒントの改善を目的としています。

ExtractResult オブジェクトは以下の属性を持ちます。

属性名 説明 例 (https://forums.news.google.co.uk)
subdomain サブドメイン部分 forums.news
domain ドメイン名部分 google
suffix Public Suffix部分 co.uk
registered_domain 登録ドメイン (domain + suffix) google.co.uk
fqdn 完全修飾ドメイン名 (subdomain + domain + suffix) forums.news.google.co.uk
is_private SuffixがPSLのプライベートセクション由来か (要 include_psl_private_domains=True) False (デフォルト)

tldextract の核となるのが Public Suffix List (PSL) です。PSLがなければ、.co.uk.com.au のようなサフィックスを正確に認識することはできません。

PSLとは?

PSLは、Mozilla Foundationが中心となってメンテナンスしている、インターネット上でユーザーが直接名前を登録できるドメイン名の末尾部分(サフィックス)のリストです。単なるTLD (.com, .jp など) のリストではなく、.uk の下の .co.uk.ac.uk、あるいは都道府県名の .fukuoka.jp など、複数のレベルにまたがるサフィックスも定義されています。

このリストは、主にウェブブラウザがセキュリティポリシー(特にクッキーのスコープ制限)を正しく適用するために作成されました。例えば、example.com.com に対して広範囲なクッキー(スーパークッキー)を設定できないようにしたり、myblog.blogspot.comanotherblog.blogspot.com のクッキーを読み書きできないようにしたりするために使われます。

PSLはICANN管理下のgTLDやccTLDだけでなく、有志によって提出される「プライベートドメイン」(例: blogspot.com)も含まれています。

なぜ tldextract は PSL を使うのか?

URLから意味のあるドメイン部分(ユーザーや組織が登録した部分)を抽出するには、どこまでが公開されたサフィックスで、どこからが登録可能な部分なのかを知る必要があります。単純なルールベース(例:「最後のドットの後ろ」や「最後の2つの要素」)では、.co.uk のような複数レベルのサフィックスや、parliament.uk のような例外(.uk は通常 .co.uk のようなセカンドレベルが必要だが、一部例外がある)に対応できません。

PSLはこれらの複雑なケースを網羅したリストを提供しているため、tldextract はこのリストを参照することで、より正確なドメイン分割を実現しています。

PSLの更新の重要性

新しいgTLDは継続的に追加されており、ccTLDの構造ルールが変更されたり、プライベートドメインが追加・削除されたりすることもあります。そのため、PSLは常に更新されています。

tldextract が正確な結果を返し続けるためには、参照しているPSLデータが最新であることが重要です。前述のキャッシュ更新機能は、このための仕組みです。長期間キャッシュを更新しないと、新しいドメインサフィックスを正しく認識できなかったり、古いルールに基づいて誤った分割をしてしまったりする可能性があります。

PSLをドメイン名の有効性チェックに使わないこと: PSLはあくまで「どこまでが公開サフィックスか」を定義するリストであり、「存在する有効なドメイン名か」を判定するためのものではありません。gTLDやccTLDは常に変化しており、リストに載っていても実際に登録可能とは限りませんし、リストに載っていなくても有効な場合があります。ドメイン名の有効性を確認するには、DNSルックアップなど、適切な方法を使用する必要があります。

PSLに関する詳細は、Public Suffix List の公式サイト を参照してください。

  • キャッシュ管理: プロダクション環境では、初回実行時のHTTPリクエストを避けるため、ビルド時やデプロイ時にキャッシュを事前生成するか、キャッシュ更新プロセスを管理下に置くことを強く推奨します。定期的なキャッシュ更新も忘れずに行いましょう。
  • URLの事前検証: tldextract は入力に寛容ですが、予期せぬ入力は予期せぬ結果を招きます。特に外部からの入力を扱う場合は、事前にURLの形式が妥当であるか検証することが望ましいです。
  • IPアドレスの扱い: IPアドレスを入力した場合、ドメイン部分にIPアドレス全体が、サフィックスは空文字列として返されます。IPアドレスかどうかを判定したい場合は、別途チェックが必要です。
  • Punycode対応: 国際化ドメイン名 (IDN) は Punycode 形式 (例: xn--eckwd4c7c.jp) で表現されることがあります。tldextract は Punycode 形式のドメインも処理できます (内部で idna ライブラリを使用)。
  • パフォーマンス: 大量のURLを処理する場合、毎回 tldextract.extract() を呼び出すのではなく、TLDExtract オブジェクトを一度生成して使い回す方が効率的です。キャッシュが有効であれば、2回目以降の呼び出しは高速です。それでもパフォーマンスがボトルネックになる場合は、キャッシュの無効化や、より低レベルな処理への切り替えを検討する必要があるかもしれません(ただし、通常はキャッシュがあれば十分高速です)。
  • プライベートドメインの認識: デフォルトではプライベートドメインをサフィックスとして扱わないことを念頭に置いてください。必要に応じて include_psl_private_domains=True を使用します。
  • ライブラリのアップデート: tldextract 自体もバグ修正や機能改善、同梱PSLスナップショットの更新が行われます。定期的にライブラリのバージョンを確認し、必要に応じてアップデートしましょう。アップデート後はキャッシュの削除も検討してください。
  • エラーハンドリング: ネットワークエラー(キャッシュ更新時)やファイルI/Oエラー(キャッシュ読み書き時)が発生する可能性を考慮し、必要に応じて例外処理を実装します。

tldextract は様々な場面で活用できます。

  • ウェブサイトの分類: registered_domain を使って、同じ組織やサービスに属するURLをグルーピングする。例えば、ウェブサーバーのアクセスログを分析し、ドメインごとにトラフィックを集計する。
    import tldextract
    from collections import Counter
    
    access_log = [
        'http://www.google.com/search?q=a',
        'https://mail.google.com/inbox',
        'https://news.google.com/',
        'http://www.bbc.co.uk/news',
        'https://forums.bbc.co.uk/discussion',
        'https://example.com/page1',
    ]
    
    domain_counts = Counter()
    for url in access_log:
        ext = tldextract.extract(url)
        if ext.registered_domain: # ドメインが取得できた場合のみカウント
            domain_counts[ext.registered_domain] += 1
    
    print(domain_counts)
    # Counter({'google.com': 3, 'bbc.co.uk': 2, 'example.com': 1})
    
  • セキュリティ分析:
    • フィッシングサイト検出支援: 抽出されたドメイン名 (domain) が、既知のブランド名と酷似していないか (タイポスクワッティング)、または信頼できないサフィックス (suffix) を使用していないかチェックする。
    • ドメインのホワイトリスト/ブラックリスト判定: registered_domain が安全なドメインリストに含まれているか、または危険なドメインリストに含まれているかを確認する。
    import tldextract
    
    whitelist = {'google.com', 'example.org', 'github.com'}
    blacklist = {'malicious-site.biz', 'phishing-scam.xyz'}
    
    urls_to_check = [
        'https://safe.example.org/login',
        'http://www.google.com.evil.com/steal', # 悪意のあるサブドメイン
        'https://very-bad.phishing-scam.xyz/account',
        'https://github.com/user/repo',
    ]
    
    for url in urls_to_check:
        ext = tldextract.extract(url)
        reg_dom = ext.registered_domain
        if reg_dom in whitelist:
            print(f"[SAFE] {url} (ドメイン: {reg_dom})")
        elif reg_dom in blacklist:
            print(f"[DANGER] {url} (ドメイン: {reg_dom})")
        else:
            # ドメイン自体はリストにないが、サブドメイン等で判断が必要な場合など
            if 'evil.com' in url: # より高度なチェックが必要な例
                 print(f"[SUSPICIOUS] {url} (ドメイン: {reg_dom})")
            else:
                 print(f"[UNKNOWN] {url} (ドメイン: {reg_dom})")
    
  • SEO (検索エンジン最適化):
    • 競合サイトのサブドメイン構造を分析する。
    • 被リンクのドメインレベル(ルートドメイン、サブドメイン)を分類する。
  • データクレンジング: 大量のURLデータから、正規化されたドメイン情報(例: registered_domain)を抽出し、分析しやすい形式に整形する。
  • ネットワーク監視: ネットワークトラフィックログから、アクセス先のドメイン情報を抽出し、不審な通信がないか監視する。

Pythonライブラリ tldextract は、Public Suffix List を活用することで、単純な文字列処理では困難なURLからの正確なドメイン情報(サブドメイン、ドメイン、サフィックス)の抽出を可能にする、非常に強力で便利なツールです。

キャッシュ機能によるパフォーマンスの最適化、プライベートドメインやカスタムサフィックスへの対応など、柔軟な設定も可能です。一方で、キャッシュ管理やURLの事前検証、PSLの更新といった注意点も理解しておくことが重要です。

Web開発、データ分析、セキュリティ、SEOなど、URLを扱うあらゆる場面で tldextract は活躍します。ぜひこのライブラリを活用して、あなたのプロジェクトをより洗練されたものにしてください!💪

さらに詳しい情報や最新のアップデートについては、公式GitHubリポジトリ を参照することをお勧めします。

コメント

タイトルとURLをコピーしました