# -*- coding: UTF-8 -*- ''' @Project :domainScanDemo @File :domain_utils.py @IDE :PyCharm @Author :梦伴 @Date :2026/4/9 0:05 @explain : 域名工具类 ''' import re import tldextract from loguru import logger def normalize_domain(domain): """ 标准化域名 :param domain: 域名 :return: str - 标准化后的域名 """ try: # 转换为小写 domain = domain.lower() # 去除空格 domain = domain.strip() # 去除协议 domain = re.sub(r'^https?://', '', domain) # 去除路径和查询参数 domain = domain.split('/')[0] domain = domain.split('?')[0] # 去除端口 domain = domain.split(':')[0] # 只保留主域 ext = tldextract.extract(domain) if ext.domain and ext.suffix: domain = f"{ext.domain}.{ext.suffix}" # 验证域名格式 if not is_valid_domain(domain): return None return domain except Exception as e: logger.error(f"标准化域名出错: {e}") return None def is_valid_domain(domain): """ 验证域名格式 :param domain: 域名 :return: bool - 是否有效 """ try: # 域名格式正则 pattern = r'^[a-zA-Z0-9][a-zA-Z0-9-]{0,61}[a-zA-Z0-9]\.[a-zA-Z]{2,}$' return bool(re.match(pattern, domain)) except Exception as e: logger.error(f"验证域名格式出错: {e}") return False def extract_tld(domain): """ 提取顶级域名 :param domain: 域名 :return: str - 顶级域名 """ try: ext = tldextract.extract(domain) return ext.suffix except Exception as e: logger.error(f"提取顶级域名出错: {e}") return '' def extract_domain(domain): """ 提取主域名 :param domain: 域名 :return: str - 主域名 """ try: ext = tldextract.extract(domain) if ext.domain and ext.suffix: return f"{ext.domain}.{ext.suffix}" return domain except Exception as e: logger.error(f"提取主域名出错: {e}") return domain def is_com_or_net(domain): """ 检查是否为 .com 或 .net 域名 :param domain: 域名 :return: bool - 是否为 .com 或 .net 域名 """ try: tld = extract_tld(domain) return tld in ['com', 'net'] except Exception as e: logger.error(f"检查域名后缀出错: {e}") return False def generate_domain_variants(domain): """ 生成域名变体 :param domain: 域名 :return: list - 域名变体列表 """ try: variants = [] # 原始域名 variants.append(domain) # 添加 www if not domain.startswith('www.'): variants.append(f"www.{domain}") # 移除 www if domain.startswith('www.'): variants.append(domain[4:]) return variants except Exception as e: logger.error(f"生成域名变体出错: {e}") return [domain] def parse_domain_status(status_code): """ 解析域名状态码 :param status_code: 状态码 :return: str - 状态描述 """ status_map = { 0: '待检测', 1: '可注册', 2: '已注册', 3: '宽限期', 4: '赎回期', 5: '删除期', 6: 'clientHold', 7: 'serverHold', 8: '状态未知', 9: '检测失败' } return status_map.get(status_code, '未知') def parse_use_status(status_code): """ 解析使用状态码 :param status_code: 状态码 :return: str - 状态描述 """ status_map = { 0: '未使用', 1: '已经使用', 2: '已经卖出', 3: '已经预定' } return status_map.get(status_code, '未知') def parse_detect_status(status_code): """ 解析检测状态码 :param status_code: 状态码 :return: str - 状态描述 """ status_map = { 0: '待检测', 1: '检测中', 2: '正常', 3: '黑名单', 4: '检测失败', 5: '暂停检测' } return status_map.get(status_code, '未知') def parse_source_type(source_type): """ 解析来源类型 :param source_type: 来源类型 :return: str - 来源描述 """ source_map = { 1: '聚名一口价', 2: '聚名过期删除', 3: 'zone file', 4: '搜索引擎采集', 5: '企业目录采集', 6: '手工录入', 7: 'TXT 导入', 8: '第三方接口', 9: '其它' } return source_map.get(source_type, '未知')