129 lines
3.8 KiB
Python
129 lines
3.8 KiB
Python
# -*- coding: UTF-8 -*-
|
|
'''
|
|
@Project :domainScanDemo
|
|
@File :rdap_detector.py
|
|
@IDE :PyCharm
|
|
@Author :梦伴
|
|
@Date :2026/4/8 23:56
|
|
@explain : RDAP检测器
|
|
'''
|
|
|
|
import requests
|
|
from app.detectors.base import BaseDetector
|
|
|
|
|
|
class RDAPDetector(BaseDetector):
|
|
"""
|
|
RDAP检测器
|
|
"""
|
|
|
|
def __init__(self):
|
|
"""
|
|
初始化RDAP检测器
|
|
"""
|
|
super().__init__()
|
|
self.rdap_urls = {
|
|
'com': 'https://rdap.verisign.com/com/v1/domain/',
|
|
'net': 'https://rdap.verisign.com/net/v1/domain/'
|
|
}
|
|
|
|
def check_domain(self, domain):
|
|
"""
|
|
检测域名
|
|
|
|
:param domain: 域名
|
|
:return: dict - 检测结果
|
|
"""
|
|
try:
|
|
# 提取顶级域名
|
|
tld = domain.split('.')[-1]
|
|
if tld not in self.rdap_urls:
|
|
return {'error': '不支持的顶级域名'}
|
|
|
|
# 构建RDAP查询URL
|
|
url = self.rdap_urls[tld] + domain
|
|
|
|
# 发送请求
|
|
response = requests.get(url, timeout=10)
|
|
|
|
if response.status_code == 200:
|
|
data = response.json()
|
|
return self._parse_rdap_response(data)
|
|
elif response.status_code == 404:
|
|
return {'status': 'available'}
|
|
else:
|
|
return {'error': f'RDAP查询失败: {response.status_code}'}
|
|
except Exception as e:
|
|
return self._handle_exception(e, domain)
|
|
|
|
def check_register_status(self, domain):
|
|
"""
|
|
检查注册状态
|
|
|
|
:param domain: 域名
|
|
:return: int - 注册状态码
|
|
"""
|
|
try:
|
|
result = self.check_domain(domain)
|
|
|
|
if 'error' in result:
|
|
return 9 # 状态未知
|
|
|
|
if result.get('status') == 'available':
|
|
return 2 # 可注册
|
|
|
|
# 检查域名状态
|
|
statuses = result.get('statuses', [])
|
|
if 'clientHold' in statuses:
|
|
return 7 # clientHold
|
|
elif 'serverHold' in statuses:
|
|
return 8 # serverHold
|
|
elif 'autoRenewPeriod' in statuses:
|
|
return 4 # 宽限期
|
|
elif 'redemptionPeriod' in statuses:
|
|
return 5 # 赎回期
|
|
elif 'pendingDelete' in statuses:
|
|
return 6 # 删除期
|
|
else:
|
|
return 3 # 已注册
|
|
except Exception as e:
|
|
self._handle_exception(e, domain)
|
|
return 10 # 检测失败
|
|
|
|
def _parse_rdap_response(self, data):
|
|
"""
|
|
解析RDAP响应
|
|
|
|
:param data: RDAP响应数据
|
|
:return: dict - 解析结果
|
|
"""
|
|
result = {
|
|
'status': 'registered',
|
|
'domain': data.get('ldhName'),
|
|
'statuses': data.get('status', []),
|
|
'registrar': None,
|
|
'creation_date': None,
|
|
'expiration_date': None,
|
|
'last_update': None
|
|
}
|
|
|
|
# 解析注册商信息
|
|
for entity in data.get('entities', []):
|
|
if 'registrar' in entity.get('roles', []):
|
|
result['registrar'] = entity.get('vcardArray', [[], []])[1][1][3]
|
|
break
|
|
|
|
# 解析时间信息
|
|
for event in data.get('events', []):
|
|
event_action = event.get('eventAction')
|
|
event_date = event.get('eventDate')
|
|
|
|
if event_action == 'registration':
|
|
result['creation_date'] = event_date
|
|
elif event_action == 'expiration':
|
|
result['expiration_date'] = event_date
|
|
elif event_action == 'last update':
|
|
result['last_update'] = event_date
|
|
|
|
return result
|