域名注册检测工具 域名Whois查询

这是一个 C# 控制台应用程序,用于批量检测由键盘左手区字母组成的 3-4 字母.com 域名是否可注册。

核心功能

\1. 域名生成

  • 左手区字母:QWERTY, ASDFG, ZXCVB(共 16 个字母)

  • 域名长度:3-4 个字母 + .com 后缀

  • 生成数量:16³ + 16⁴ = 4096 + 65536 = 69632 个域名

\2. API 检测

  • API 地址:https://api.uutool.cn/whois/info/?biz=log.js

  • 请求方式:POST

  • 检测参数:domain=xxx.com

  • 结果判断:根据 available 字段判断是否可注册

\3. 断点续传

  • 已检测域名记录:checked_domains.txt

  • 避免重复检测:程序启动时自动加载已检测域名

  • 实时保存进度:每检测一个域名就保存到文件

\4. 结果保存

  • 可注册域名:available_domains.txt

  • 错误域名:errordomain.txt

  • 已检测域名:checked_domains.txt

C# 7.0 语法特性

  • 使用async/await进行异步操作

  • var类型推断

  • 字符串插值

  • 异常处理改进

性能优化

  • 请求间隔:1 秒间隔避免 API 限制

  • 批次处理:每 100 个域名批次保存

  • 内存优化:按需生成和检测域名

错误处理

  • 网络错误处理

  • API 响应错误处理

  • 异常捕获和记录

  • 程序崩溃后可恢复

这个工具可以帮助您高效地检测大量域名,找到可注册的优质域名资源。程序设计考虑了各种异常情况和性能优化,确保长时间稳定运行。

using System;
using System.Collections.Generic;
using System.IO;
using System.Net.Http;
using System.Threading.Tasks;
using System.Web;
using Newtonsoft.Json;

namespace DomainChecker_WhoisCX
{
    class Program
    {
        // 键盘左手区字母(QWERTY行、ASDFG行、ZXCVB行)
        private static readonly char[] LeftHandChars = {
            'q', 'w', 'e', 'r', 't', // QWERTY行
            'a', 's', 'd', 'f', 'g', // ASDFG行
            'z', 'x', 'c', 'v', 'b'  // ZXCVB行
        };

        // WhoisCX API配置
        private const string ApiUrl = "https://api.whoiscx.com/whois/";
        private const int RequestInterval = 2000; // API限制2秒/次(2000毫秒)

        // HttpClient单例(避免频繁创建)
        private static readonly HttpClient _httpClient = new HttpClient();

        static void Main(string[] args)
        {
            Console.WriteLine("开始检测左手区字母组合的.com域名注册状态(WhoisCX API)...");
            Console.WriteLine("=============================================\n");

            try
            {
                // 遍历2-4字符组合(C#7需用Wait()阻塞主线程)
                //Console.WriteLine("【2字符组合检测】");
                //GenerateAndCheckDomains(2).Wait();

                Console.WriteLine("\n【3字符组合检测】");
                GenerateAndCheckDomains(3).Wait();

                Console.WriteLine("\n【4字符组合检测】");
                GenerateAndCheckDomains(4).Wait();
            }
            catch (AggregateException ex)
            {
                Console.WriteLine($"检测过程出错: {ex.InnerException?.Message}");
            }

            Console.WriteLine("\n所有域名检测完成!");
            Console.ReadLine();
        }

        /// <summary>
        /// 生成指定长度的字母组合并检测域名状态
        /// </summary>
        /// <param name="length">字符长度(2-4)</param>
        private   static async Task GenerateAndCheckDomains(int length)
        {
            var combinations = new List<string>();
            GenerateCombinations("", length, combinations);

            foreach (var combo in combinations)
            {
                var domain = $"{combo}.com";
                try
                {
                    Console.WriteLine($"正在检测: {domain}");
                    var checkResult = await CheckDomainStatus(domain);

                    // 解析并输出结果
                    var statusDesc = checkResult.IsAvailable == 1
                        ? "✅ 可注册"
                        : $"❌ 已注册(过期状态:{(checkResult.IsExpire == 1 ? "已过期" : "未过期")})";
                    if (checkResult.IsAvailable == 1)
                    {
                          File.AppendAllText("可注册域名.txt", $"{domain}\n");
                    }
                    Console.WriteLine($"域名: {domain} | 状态: {statusDesc}");
                }
                catch (Exception ex)
                {
                    Console.WriteLine($"域名: {domain} | 检测失败: {ex.Message}");
                }

                // 严格遵循API频次限制:2秒/次
                await Task.Delay(RequestInterval);
            }
        }

        /// <summary>
        /// 递归生成左手区字母组合
        /// </summary>
        private static void GenerateCombinations(string current, int length, List<string> result)
        {
            if (current.Length == length)
            {
                result.Add(current);
                return;
            }

            foreach (var c in LeftHandChars)
            {
                GenerateCombinations(current + c, length, result);
            }
        }

        /// <summary>
        /// 调用WhoisCX API检测域名状态
        /// </summary>
        /// <param name="domain">要检测的域名(如asdf.com)</param>
        /// <returns>域名检测结果</returns>
        private static async Task<DomainCheckResult> CheckDomainStatus(string domain)
        {
            // 构建API请求URL(编码域名,避免特殊字符问题)
            var encodedDomain = HttpUtility.UrlEncode(domain);
            var requestUrl = $"{ApiUrl}?domain={encodedDomain}&raw=1";

            // 发送GET请求
            var response = await _httpClient.GetAsync(requestUrl);
            response.EnsureSuccessStatusCode();

            // 读取并解析JSON响应
            var json = await response.Content.ReadAsStringAsync();
            var apiResponse = JsonConvert.DeserializeObject<WhoisCxResponse>(json);

            // 验证API响应状态
            if (apiResponse.Status != 1)
            {
                throw new Exception($"API返回失败:{json}");
            }

            // 提取核心检测结果
            return new DomainCheckResult
            {
                Domain = apiResponse.Data.Domain,
                IsAvailable = apiResponse.Data.IsAvailable,
                IsExpire = apiResponse.Data.Info.IsExpire,
                DomainStatus = apiResponse.Data.Info.DomainStatus,
                RawInfo = apiResponse.Data.Raw
            };
        }
    }

    #region 数据模型(匹配WhoisCX API响应格式)
    /// <summary>
    /// API顶层响应模型
    /// </summary>
    public class WhoisCxResponse
    {
        [JsonProperty("status")]
        public int Status { get; set; }

        [JsonProperty("data")]
        public WhoisCxData Data { get; set; }
    }

    /// <summary>
    /// API返回的Data字段模型
    /// </summary>
    public class WhoisCxData
    {
        [JsonProperty("is_available")]
        public int IsAvailable { get; set; }

        [JsonProperty("domain")]
        public string Domain { get; set; }

        [JsonProperty("domain_suffix")]
        public string DomainSuffix { get; set; }

        [JsonProperty("query_time")]
        public string QueryTime { get; set; }

        [JsonProperty("info")]
        public WhoisCxInfo Info { get; set; }

        [JsonProperty("raw")]
        public string Raw { get; set; }
    }

    /// <summary>
    /// API返回的Info字段模型
    /// </summary>
    public class WhoisCxInfo
    {
        [JsonProperty("domain")]
        public string Domain { get; set; }

        [JsonProperty("registrant_name")]
        public string RegistrantName { get; set; }

        [JsonProperty("registrant_email")]
        public string RegistrantEmail { get; set; }

        [JsonProperty("registrar_name")]
        public string RegistrarName { get; set; }

        [JsonProperty("creation_time")]
        public string CreationTime { get; set; }

        [JsonProperty("expiration_time")]
        public string ExpirationTime { get; set; }

        [JsonProperty("creation_days")]
        public int CreationDays { get; set; }

        [JsonProperty("valid_days")]
        public int ValidDays { get; set; }

        [JsonProperty("is_expire")]
        public int IsExpire { get; set; }

        [JsonProperty("domain_status")]
        public List<string> DomainStatus { get; set; }

        [JsonProperty("name_server")]
        public List<string> NameServer { get; set; }

        [JsonProperty("whois_server")]
        public string WhoisServer { get; set; }
    }

    /// <summary>
    /// 简化的域名检测结果模型
    /// </summary>
    public class DomainCheckResult
    {
        public string Domain { get; set; }
        public int IsAvailable { get; set; } // 1=可注册,0=已注册
        public int IsExpire { get; set; }    // 1=已过期,0=未过期
        public List<string> DomainStatus { get; set; }
        public string RawInfo { get; set; }
    }
    #endregion
}