如何用Node.js高效可靠地批量检测域名可用性?
域名可用性批量检测解决方案(Node.js/Shell)
一、核心问题分析
- DNSimple API速率限制:官方接口有严格请求配额,无法支撑数千域名的批量检测需求
- DNS查询误报原因:
- NXDOMAIN状态不代表域名一定未注册,部分注册商会给未注册域名配置默认解析记录
- 仅检测A记录维度单一,需结合NS、WHOIS等多维度验证
- WHOIS查询误报原因:
- 不同注册商的WHOIS返回格式差异大,单一正则规则无法覆盖所有场景
- WHOIS服务器超时、限流会导致数据获取不全,进而判断错误
二、可行解决方案
1. Node.js优化方案:DNS+WHOIS交叉验证+并发控制
通过多维度验证减少误报,同时控制并发量避免被限流:
const dns = require("dns"); const whois = require("whois"); const fs = require("fs"); // 检测NS记录:存在NS记录则域名已注册 async function checkDNS(domain) { return new Promise((resolve) => { dns.resolveNs(domain, (err) => { resolve(err?.errno === dns.NXDOMAIN); }); }); } // WHOIS检测:匹配多厂商可用标识,排除已注册关键词 async function checkWHOIS(domain) { return new Promise((resolve) => { whois.lookup(domain, { timeout: 3000 }, (err, data) => { if (err) { resolve(null); // 超时标记为待确认 return; } const isAvailable = /(available|not registered|no match)/i.test(data) && !/(registered|created|expires)/i.test(data); resolve(isAvailable); }); }); } // 交叉验证:两者都判定可用才标记为可用 async function checkDomain(domain) { const dnsResult = await checkDNS(domain); const whoisResult = await checkWHOIS(domain); if (dnsResult && whoisResult === true) { return { domain, status: "available" }; } else if (whoisResult === false || !dnsResult) { return { domain, status: "taken" }; } else { return { domain, status: "pending" }; } } // 批量检测主逻辑,带并发控制 async function start() { const words = ["foo", "bar", "baz"]; const tlds = ["link", "site", "host", "surf"]; const results = []; const concurrencyLimit = 10; // 控制并发数,避免被封 let activeRequests = 0; const queue = []; // 生成检测任务队列 for (const tld of tlds) { for (const word of words) { const domain = `${word}.${tld}`; queue.push(async () => { activeRequests++; const result = await checkDomain(domain); results.push(result); console.log(`${domain} - ${result.status}`); activeRequests--; }); } } // 处理队列,控制并发 while (queue.length > 0 || activeRequests > 0) { if (activeRequests < concurrencyLimit && queue.length > 0) { const task = queue.shift(); task(); } await new Promise(resolve => setTimeout(resolve, 100)); } // 导出可用域名 const availableDomains = results.filter(r => r.status === "available").map(r => r.domain); fs.writeFileSync("available_domains.csv", availableDomains.join("\n")); console.log("检测完成,结果已导出"); } start();
2. Shell脚本方案(轻量场景)
利用系统自带的whois和dig命令实现批量检测:
#!/bin/bash WORDS=("foo" "bar" "baz") TLDS=("link" "site" "host" "surf") OUTPUT="available_domains.txt" > "$OUTPUT" # 清空输出文件 for tld in "${TLDS[@]}"; do for word in "${WORDS[@]}"; do domain="$word.$tld" # 先查WHOIS确认可用 whois "$domain" | grep -qi "available" if [ $? -eq 0 ]; then # 再查NS记录二次验证 dig +short ns "$domain" | grep -q . if [ $? -ne 0 ]; then echo "$domain" >> "$OUTPUT" echo "Found available: $domain" fi fi sleep 0.5 # 添加延迟,避免触发限流 done done echo "检测完成,结果已保存到$OUTPUT"
3. 第三方API选择
- 部分域名注册商(如Namecheap、GoDaddy)提供更高配额的检测API,免费额度可达数千次/小时
- 专业域名检测服务:部分支持批量查询,可根据需求选择低成本付费套餐
三、关于tld-list.com功能差异的说明
tld-list.com支持foo.*但不支持*.sometld的原因:
foo.*是遍历已知TLD列表检测同一前缀的可用性,技术实现简单,请求量可控*.sometld需要遍历无限多的前缀组合,不仅技术成本极高,还会触发注册商的反爬机制,同时涉及合规风险,因此没有服务会提供这类功能
四、无速率限制检测的可行性
完全无限制的可靠检测无法实现,核心原因:
- 所有注册商的WHOIS、DNS服务器都有请求频率限制,防止滥用
- 高频批量检测会被识别为恶意爬取,导致IP被封禁
- 域名注册系统是分布式架构,实时检测需同步多数据源,高频请求会给系统带来巨大压力
最优方案是控制并发数+添加合理延迟+多维度交叉验证,在效率和可靠性之间取得平衡
内容的提问来源于stack exchange,提问作者Lance Pollard
相关产品推荐
相关产品推荐

