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

如何从Cisco Umbrella Top 100万域名列表中移除子域名?

移除域名列表中子域名的高效方案(Bash + 优化后的Python)

针对你处理Cisco Umbrella Top 100万域名列表的需求,我提供两种高效方案:一种是用Bash命令行工具快速处理,另一种是优化你的Python代码,彻底解决耗时问题。

一、Bash命令实现思路与代码

核心思路是通过反转域名排序,让主域名(比如google.com)排在其子域名(比如play.google.com)前面,然后遍历过程中记录已保留的主域名,遇到子域名直接跳过。

步骤1:提取域名列(原文件是CSV,第二列为域名)

cut -d',' -f2 top-1m.csv > raw_domains.txt

步骤2:移除子域名并保留主域名

用awk处理,实现反转排序+子域名过滤:

awk -F. '{
    # 反转域名(如 play.google.com → com.google.play),便于排序后主域名在前
    reversed = ""
    for (i = NF; i > 0; i--) {
        reversed = reversed $i (i > 1 ? "." : "")
    }
    reversed_dom[NR] = reversed
    original_dom[NR] = $0
}
END {
    # 按反转后的域名排序
    asort(reversed_dom, sorted_reversed)
    seen = {}
    for (i = 1; i <= length(sorted_reversed); i++) {
        # 找到对应的原始域名并标记已处理
        for (j = 1; j <= NR; j++) {
            if (reversed_dom[j] == sorted_reversed[i] && original_dom[j] != "") {
                curr_dom = original_dom[j]
                original_dom[j] = ""
                break
            }
        }
        # 检查当前域名是否是已保留主域名的子域
        is_sub = 0
        split(sorted_reversed[i], parts, ".")
        prefix = parts[1]
        for (k = 2; k <= length(parts); k++) {
            prefix = prefix "." parts[k]
            if (prefix in seen) {
                is_sub = 1
                break
            }
        }
        if (!is_sub) {
            print curr_dom
            seen[sorted_reversed[i]] = 1
        }
    }
}' raw_domains.txt > cleaned_main_domains.txt

步骤3:统计剩余域名数量

wc -l cleaned_main_domains.txt

二、Python代码优化方案

你原来的代码问题在于O(n²)的时间复杂度——每个域名都要和100万条数据比对,这相当于1e12次操作,完全不现实。优化思路是利用集合的O(1)查找特性,将比对复杂度降到线性。

优化后的代码

import csv

def get_parent_domains(domain):
    """生成当前域名的所有可能父域(排除顶级域)"""
    parts = domain.split('.')
    parents = []
    # 生成从二级域开始的父域,比如 play.google.com → [google.com]
    for i in range(1, len(parts)-1):
        parent = '.'.join(parts[i:])
        parents.append(parent)
    return parents

def main():
    # 读取所有域名,存入集合用于快速查找
    domain_set = set()
    domain_list = []
    
    with open("top-1m.csv", "r") as f:
        reader = csv.reader(f, delimiter=',')
        for row in reader:
            domain = row[1].strip()
            domain_list.append(domain)
            domain_set.add(domain)
    
    # 筛选主域名:没有任何父域在原列表中的域名
    main_domains = []
    for domain in domain_list:
        is_subdomain = False
        for parent in get_parent_domains(domain):
            if parent in domain_set:
                is_subdomain = True
                break
        if not is_subdomain:
            main_domains.append(domain)
    
    # 保存结果并统计数量
    with open("cleaned_main_domains.txt", "w") as f:
        for dom in main_domains:
            f.write(f"{dom}\n")
    
    print(f"处理完成!剩余主域名数量:{len(main_domains)}")

if __name__ == "__main__":
    main()

优化说明

  • 时间复杂度从O(n²)降到了O(n*k),其中k是域名的平均段数(一般为2-3),100万条数据几分钟就能处理完。
  • 利用集合的快速查找特性,避免了嵌套循环的暴力比对。
  • 额外处理了域名的空白字符,避免格式问题。

如果需要排除顶级域(比如com、net这类单独出现的域名),可以在筛选时加个判断:

if len(domain.split('.')) < 2:
    continue

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 21:57:29