[Python] whoisでドメイン登録日を取得する方法

ドメイン情報は「whois」で取得することができますが、情報が登録ドメインによって異なります。
pythonにはwhoisモジュールがありますが、これを使用するとjpは場合によって情報を返さない場合があります。

今回紹介する方法は正直全部を網羅していません。
が、ある程度日本でよく使われるドメインについてはカバーできたので今回はPythonでドメイン登録日を取得する方法を紹介します。

## 実行結果
ドメイン登録日 : 対象URL

```
2015-05-21: https://example.com
2017-06-25: https://example.jp
2015-02-22: https://example.net
2021-01-05: https://example.co.jp
2013-02-01: https://example.info
```

## 実行環境
Python 3.9
pip3 22.0.4

## コード

```python
import json
import subprocess
import time
from tld import get_tld
import re


""" 検証済みドメイン登録日
       .jp => [Created on]
       .co.jp => [Registered Date]
       .ad.jp => [Registered Date]
       .net => Creation Date
       .com => Creation Date
       .org => Creation Date
       .it => Created
       .info => Creation Date
       .biz =>  Creation Date
       など
"""

# 検証したいURLを配列に
test_urls = [
    'https://example.com',
    'https://example.jp',
    'https://example.net',
    'https://example.co.jp',
    'https://example.info'
]

def get_domain_created_date(domain_info):
    """ 取得したドメイン情報をもとに登録日を取得 """
    created_date = ""
    search_word = ""
    sub_info = ""
    word_position = ""

    if 'Creation Date' in domain_info:
        search_word = r'Creation Date(.*)'
        sub_info = re.search(search_word, domain_info).group(1)
        word_position = r'\d{4}-\d{2}-\d{2}'

    elif 'Registered Date' in domain_info:
        search_word = r'\[Registered Date\](.*)'
        sub_info = re.search(search_word, domain_info).group(1)
        word_position = r'\d{4}/\d{2}/\d{2}'

    elif 'Created on' in domain_info:
        search_word = r'\[Created on\](.*)'
        sub_info = re.search(search_word, domain_info).group(1)
        word_position = r'\d{4}/\d{2}/\d{2}'

    elif 'Created' in domain_info: 
        search_word = r'Created(.*)'
        sub_info = re.search(search_word, domain_info).group(1)
        word_position = r'\d{4}-\d{2}-\d{2}'
    else:
        print(domain_info)
        return 'unknown'
    
    if re.search(word_position, sub_info) is None:
        created_date = 'unknown'
    else:
        created_date = re.search(word_position, sub_info).group()
    return created_date



def test_domain():
    """ URLをもとにドメイン情報を取得しドメイン登録日を出力 """
    print("=====Start=====")
    for url in test_urls:
        target_url = url
        domain = get_tld(target_url, as_object=True).fld
        domain_info = subprocess.run(f"whois -k {domain}", shell=True, capture_output=True, text=True).stdout

        created_date = get_domain_created_date(domain_info).replace('/', '-')
        print(f"{created_date}:{target_url}")
        time.sleep(1)
    print("=====End=====")

test_domain()

```


### 解説
全体としては大したことしてないですが補足で以下解説です。

実行の主体は```test_domain()```になります。この関数では、
① tldモジュールでドメインを取得し、subprocessで```whois -k domain```を実行します。
   ↑実行後、返す値が```process Class```なのでstringに置換します。
   コマンドの```-k```はKoreanサーバーを経由して取得しています。まんま whois を実行するとjpは日本語で情報を返す場合があり、その場合この後の処理で面倒になります。```-k```で実行すると英語で返してくれます。
   ※tldモジュールは各自インストールしてください。
② 大体の検証結果から```Creation Date | Registered Date | Created on | Created```のどれかで登録日を返してくれます。これを利用して、テキスト置換した①からドメイン登録表示を判定・取得します。
③ 登録ドメインによって日付フォーマットが異なるのでreplaceで「Y-m-d」に整えて出力します。

```get_domain_created_date()```では該当するドメイン情報に応じて正規表現で登録日を抽出しています。
ドメインによっては②の登録パターンに該当したものの、うまく取得できない場合も想定されるので、その場合は```unknown```で返すようにしています。別のプロパティで補完している可能性もあるので、その辺りは別で検証する必要があります。

### まとめ
以上、whoisでドメイン登録日を取得する方法でした。
whoisで返すTLD情報は統一されていないので自作で抽出してみました。
単一のURLで検証する場合はforを外して、target_urlにURLを入力して実行してみてください。
あんまり需要ないかもですが使用したい方はどぞ。