You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Python中可靠检测任意TLD域名的注册状态?

可靠检测任意TLD域名注册状态的Python方案

我完全懂你这个痛点——要覆盖所有TLD还得保证检测可靠性,确实是个挺棘手的问题。你试过的几个方案都踩了典型的坑,下面结合这些问题给你一套综合优化的思路:

一、先梳理现有方案的核心问题

你提到的尝试都戳中了这类需求的常见瓶颈:

  • python-whois/whois库:硬编码支持的TLD有限,对.run这类新通用TLD(gTLD)覆盖不足,维护速度跟不上TLD的新增节奏;
  • 调用系统whois命令:兼容性比第三方库好,但共享IP下很容易触发WHOIS服务器的频率限制,而且不同操作系统的whois命令行为还可能有差异;
  • DNS查询:只能检测有解析记录的域名,完全覆盖不了已注册但未配置DNS、处于赎回期/删除期的域名;
  • 第三方API:隐私风险是硬伤,尤其是查询潜在优质域名时,很容易被恶意平台盯上抢注。

二、综合优化方案:自定义WHOIS查询+多维度验证+反限制策略

1. 直接对接对应TLD的官方WHOIS服务器

系统whois命令本质也是对接对应TLD的服务器,但我们自己实现这个逻辑,能更灵活地支持所有TLD:

  • 第一步:通过IANA的WHOIS服务器获取目标域名TLD的官方WHOIS地址:
    import subprocess
    
    def get_tld_whois_server(tld):
        # 从IANA查询TLD对应的官方WHOIS服务器
        try:
            result = subprocess.run(
                ['whois', '-h', 'whois.iana.org', tld],
                capture_output=True,
                text=True,
                timeout=10
            )
            for line in result.stdout.split('\n'):
                if 'whois:' in line.lower():
                    return line.split(':')[1].strip()
        except Exception as e:
            print(f"获取{TLD}的WHOIS服务器失败:{str(e)}")
        return None
    
  • 第二步:直接对接该服务器查询域名,绕开系统whois的中间层限制:
    def query_whois(domain, whois_server):
        try:
            result = subprocess.run(
                ['whois', '-h', whois_server, domain],
                capture_output=True,
                text=True,
                timeout=10
            )
            return result.stdout
        except Exception as e:
            return f"查询{whois_server}出错:{str(e)}"
    

2. 通用化WHOIS结果解析

不同TLD的WHOIS返回格式差异极大,我们可以通过关键词匹配来统一判断注册状态:

def is_domain_available(whois_output):
    # 整理各TLD通用的"域名可用"关键词
    available_keywords = [
        "no match for", "not found", "available", "is free",
        "status: available", "domain not registered", "no object found"
    ]
    # 整理各TLD通用的"域名已注册"关键词
    registered_keywords = [
        "domain name:", "registrar:", "creation date:", "status: active",
        "registered on:", "expiry date:"
    ]
    
    lower_output = whois_output.lower()
    # 优先判断是否可用
    for keyword in available_keywords:
        if keyword in lower_output:
            return True
    # 再判断是否已注册
    for keyword in registered_keywords:
        if keyword in lower_output:
            return False
    # 无法明确判断的情况(比如返回异常、格式特殊)
    return None

3. 解决IP限制问题

  • 添加随机请求延迟:每次查询后随机等待1-3秒,避免短时间内大量请求触发限制:
    import time
    import random
    
    time.sleep(random.uniform(1, 3))
    
  • 使用代理池轮询:如果是批量查询,搭配代理IP轮换(比如用socks库或requests的代理功能),避免单IP被封禁。

4. 多维度交叉验证

为了进一步提升可靠性,可以结合两种方式验证:

  • 先做DNS A/AAAA记录查询(用dnspython库),如果有记录直接判定已注册;
  • 对DNS无记录的域名,再用WHOIS查询验证,避免漏掉已注册但未配置DNS的情况;
  • 对WHOIS返回模糊的域名,可以补充查询TLD注册局的公开无隐私风险接口(部分注册局提供这类服务)。

三、完整流程示例

import subprocess
import time
import random
import dns.resolver

def get_tld_whois_server(tld):
    try:
        result = subprocess.run(
            ['whois', '-h', 'whois.iana.org', tld],
            capture_output=True,
            text=True,
            timeout=10
        )
        for line in result.stdout.split('\n'):
            if 'whois:' in line.lower():
                return line.split(':')[1].strip()
    except Exception as e:
        print(f"获取.{tld}的WHOIS服务器失败:{str(e)}")
    return None

def query_whois(domain, whois_server):
    try:
        result = subprocess.run(
            ['whois', '-h', whois_server, domain],
            capture_output=True,
            text=True,
            timeout=10
        )
        return result.stdout
    except Exception as e:
        return f"查询出错:{str(e)}"

def check_dns_record(domain):
    try:
        resolver = dns.resolver.Resolver()
        resolver.timeout = 5
        resolver.lifetime = 5
        # 查询A记录
        resolver.resolve(domain, 'A')
        return True
    except (dns.resolver.NXDOMAIN, dns.exception.Timeout, dns.resolver.NoAnswer):
        return False
    except Exception as e:
        print(f"DNS查询出错:{str(e)}")
        return None

def is_domain_available(whois_output):
    available_keywords = [
        "no match for", "not found", "available", "is free",
        "status: available", "domain not registered", "no object found"
    ]
    registered_keywords = [
        "domain name:", "registrar:", "creation date:", "status: active",
        "registered on:", "expiry date:"
    ]
    
    lower_output = whois_output.lower()
    for kw in available_keywords:
        if kw in lower_output:
            return True
    for kw in registered_keywords:
        if kw in lower_output:
            return False
    return None

def check_domain_status(domain):
    # 第一步:DNS快速判断
    dns_result = check_dns_record(domain)
    if dns_result is True:
        print(f"域名 {domain} 已注册(检测到DNS记录)")
        return False
    elif dns_result is None:
        print(f"{domain} 的DNS查询失败,切换到WHOIS查询")
    
    # 第二步:获取TLD的WHOIS服务器
    tld = domain.split('.')[-1]
    whois_server = get_tld_whois_server(tld)
    if not whois_server:
        print(f"无法获取.{tld}的WHOIS服务器")
        return None
    
    # 添加随机延迟避免限制
    time.sleep(random.uniform(1, 3))
    
    # 第三步:WHOIS查询并解析
    whois_output = query_whois(domain, whois_server)
    available = is_domain_available(whois_output)
    
    if available is True:
        print(f"域名 {domain} 可用")
    elif available is False:
        print(f"域名 {domain} 已注册(检测到WHOIS记录)")
    else:
        print(f"无法判定{domain}的状态,原始WHOIS输出:\n{whois_output}")
    
    return available

# 测试示例
check_domain_status("example.run")
check_domain_status("example.com")

四、注意事项

  • 部分TLD的WHOIS服务器需要特殊查询格式(比如.cn),可以针对这类特殊TLD单独做逻辑适配;
  • 对于处于赎回期/删除期的域名,WHOIS会返回pendingDelete这类特殊状态,这类域名虽显示已注册,但短期内会释放,需要额外判断;
  • 哪怕加了延迟和代理,也不要高频批量查询,避免触发注册局的严格限制。

内容的提问来源于stack exchange,提问作者tmt

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 06:53:02