工具分享--IP与域名提取工具

最近在干活的时候发现一个小工具,用于提取防火墙、态感等设备日志中的恶意域名和IP地址,并且带有自动去重、一键去重等功能,极大程度上提高了工作效率,豪用!

这是原文地址:

https://mp.weixin.qq.com/s/irM4e7fcc-iiPRwfJ5lw_w

下面是我改良之后的版本,新增了两个功能点

1、处理模式分为两个:

唯一IP模式:完全移除重复IP,仅保留出现一次的IP,这个可以用来对照防火墙实际封禁IP与每日记录的封禁名单有什么差别。

传统去重模式:保留重复IP的一个实例。

2、重复IP可视化

被过滤的IP以独立列表折叠展示,支持展开/收起。

重复次数按数值排序(从高到低),便于快速定位高频重复项。

html 复制代码
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>IP与域名提取工具 - 极速版</title>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
        }
         
        body {
            background: linear-gradient(135deg, #1a2a6c, #b21f1f, #1a2a6c);
            min-height: 100vh;
            display: flex;
            justify-content: center;
            align-items: center;
            padding: 20px;
            color: #fff;
            -webkit-font-smoothing: antialiased;
            -moz-osx-font-smoothing: grayscale;
        }
         
        .container {
            width: 100%;
            max-width: 1200px;
            background: rgba(0, 0, 20, 0.8);
            border-radius: 20px;
            box-shadow: 0 15px 35px rgba(0, 0, 0, 0.5);
            overflow: hidden;
            backdrop-filter: blur(10px);
            border: 1px solid rgba(255, 255, 255, 0.1);
        }
         
        header {
            background: rgba(0, 10, 30, 0.9);
            padding: 25px 40px;
            text-align: center;
            border-bottom: 2px solid #00ccff;
            position: relative;
        }
         
        h1 {
            font-size: 2.5rem;
            margin-bottom: 10px;
            background: linear-gradient(90deg, #00ccff, #00ffcc);
            -webkit-background-clip: text;
            background-clip: text;
            color: transparent;
            text-shadow: 0 0 15px rgba(0, 204, 255, 0.5);
        }
         
        .subtitle {
            color: #a0d2ff;
            font-size: 1.1rem;
            opacity: 0.9;
            max-width: 800px;
            margin: 0 auto;
            line-height: 1.6;
        }
         
        .features {
            display: flex;
            justify-content: center;
            flex-wrap: wrap;
            gap: 15px;
            margin-top: 20px;
        }
         
        .feature {
            background: rgba(0, 204, 255, 0.15);
            border-radius: 8px;
            padding: 8px 15px;
            font-size: 0.9rem;
            display: flex;
            align-items: center;
            gap: 8px;
            color: #fff;
        }
         
        .mode-toggle {
            position: absolute;
            top: 20px;
            right: 20px;
            background: rgba(0, 204, 255, 0.2);
            border-radius: 20px;
            padding: 8px 16px;
            display: flex;
            align-items: center;
            gap: 8px;
            cursor: pointer;
            transition: all 0.3s ease;
        }
         
        .mode-toggle:hover {
            background: rgba(0, 204, 255, 0.3);
        }
         
        .mode-indicator {
            width: 12px;
            height: 12px;
            border-radius: 50%;
            background: #00ff00;
            box-shadow: 0 0 8px #00ff00;
        }
         
        .mode-indicator.off {
            background: #ff5555;
            box-shadow: 0 0 8px #ff5555;
        }
         
        .tooltip {
            position: absolute;
            top: -40px;
            right: 0;
            background: rgba(0, 40, 80, 0.9);
            color: #00ffcc;
            padding: 8px 12px;
            border-radius: 8px;
            font-size: 0.8rem;
            white-space: nowrap;
            opacity: 0;
            transition: opacity 0.3s ease;
            pointer-events: none;
        }
         
        .mode-toggle:hover .tooltip {
            opacity: 1;
        }
         
        .main-content {
            display: flex;
            flex-wrap: wrap;
            padding: 30px;
            gap: 30px;
        }
         
        .input-section {
            flex: 极速版域名提取工具;
            min-width: 300px;
        }
         
        .output-section {
            flex: 1;
            min-width: 300极速版域名提取工具px;
            display: flex;
            flex-direction: column;
            gap: 30px;
        }
         
        .section-title {
            font-size: 1.4rem;
            margin-bottom: 15px;
            color: #00ccff;
            display: flex;
            align-items: center;
            gap: 10px;
        }
         
        .section-title i {
            font-size: 1.2rem;
        }
         
        textarea {
            width: 100%;
            height: 250px;
            background: rgba(0, 20, 40, 0.7);
            border: 1px solid rgba(0, 204, 255, 0.4);
            border-radius: 12px;
            padding: 20px;
            color: #fff;
            font-size: 1rem;
            resize: vertical;
            transition: all 0.3s ease;
        }
         
        textarea:focus {
            outline: none;
            border-color: #00ccff;
            box-shadow: 0 0 15px rgba(0, 204, 255, 0.4);
        }
         
        textarea::placeholder {
            color: rgba(160, 210, 255, 0.7);
        }
         
        .button-group {
            display: flex;
            gap: 15px;
            margin-top: 20px;
            flex-wrap: wrap;
        }
         
        .btn {
            flex: 1;
            min-width: 140px;
            padding: 15px 20px;
            border: none;
            border-radius: 10px;
            font-size: 1.1rem;
            font-weight: 600;
            cursor: pointer;
            transition: all 0.3s ease;
            display: flex;
            align-items: center;
            justify-content: center;
            gap: 10px;
        }
         
        .btn-primary {
            background: linear-gradient(90deg, #00a6ff, #00ffc3);
            color: #00203d;
        }
         
        .btn-secondary {
            background: rgba(255, 255, 255, 0.1);
            color: #00ccff;
            border: 1px solid rgba(0, 204, 255, 0.4);
        }
         
        .btn-orange {
            background: rgba(255, 165, 0, 0.2);
            color: #ffaa33;
            border: 1px solid rgba(255, 165, 0, 0.4);
        }
         
        .btn:hover {
            transform: translateY(-3px);
            box-shadow: 0 7px 15px rgba(0, 0, 0, 0.3);
        }
         
        .btn:active {
            transform: translateY(1px);
        }
         
        .btn-primary:hover {
            background: linear-gradient(90deg, #0095e6, #00e6b8);
        }
         
        .btn-secondary:hover {
            background: rgba(255, 255, 255, 0.15);
            border-color: #00ccff;
        }
         
        .btn-orange:hover {
            background: rgba(255, 165, 0, 0.3);
        }
         
        .results-box {
            background: rgba(0, 20, 40, 0.7);
            border: 1px solid rgba(0, 204, 255, 0.4);
            border-radius: 12px;
            padding: 20px;
            min-height: 250px;
            position: relative;
        }
         
        .box-header {
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin-bottom: 15px;
            gap: 15px;
            flex-wrap: wrap;
        }
         
        .copy-btn {
            background: rgba(0, 204, 255, 0.2);
            color: #00ccff;
            border: none;
            padding: 8px 15px;
            border-radius: 8px;
            cursor: pointer;
            transition: all 0.3s极速版域名提取工具 ease;
            display: flex;
            align-items: center;
            gap: 8px;
            flex-shrink: 0;
        }
         
        .copy-btn:hover {
            background: rgba(0, 204, 255, 0.3);
        }
         
        .results-content {
            max-height: 200px;
            overflow-y: auto;
            padding-right: 10px;
        }
         
        .results-content::-webkit-scrollbar {
            width: 8px;
        }
         
        .results-content::-webkit-scrollbar-track {
            background: rgba(0, 0, 0, 0.2);
            border-radius: 4px;
        }
         
        .results-content::-webkit-scrollbar-thumb {
            background: rgba(0, 204, 255, 0.5);
            border-radius: 4px;
        }
         
        .result-item {
            padding: 10px 15px;
            background: rgba(0, 40, 80, 0.4);
            border-radius: 8px;
            margin-bottom: 10px;
            display: flex;
            justify-content: space-between;
            align-items: center;
            animation: fadeIn 0.5s ease;
            color: #fff;
            font-weight: 500;
            letter-spacing: 0.03em;
        }
         
        .result-item.duplicate {
            background: rgba(180, 60, 60, 0.4);
            color: #ffaaaa;
            text-decoration: line-through;
        }
         
        @keyframes fadeIn {
            from { opacity: 0; transform: translateY(10px); }
            to { opacity: 1; transform: translateY(0); }
        }
         
        .result-item .copy-icon {
            color: #00ccff;
            cursor: pointer;
            font-size: 1.1rem;
            transition: all 0.2s ease;
        }
         
        .result-item .copy-icon:hover {
            color: #00ffcc;
            transform: scale(1.1);
        }
         
        .empty-message {
            color: #a0d2ff;
            text-align: center;
            padding: 20px;
            font-style: italic;
            text-shadow: 0 1px 2px rgba(0,0,0,0.5);
        }
         
        .counter {
            background: rgba(0, 204, 255, 0.2);
            border-radius: 20px;
            padding: 3px 10px;
            font-size: 0.9rem;
        }
         
        .counter.warning {
            background: rgba(255, 204, 0, 0.2);
        }
         
        .notification {
            position: fixed;
            top: 20px;
            right: 20px;
            background: rgba(0, 40, 80, 0.9);
            color: #00ffcc;
            padding: 15px 25px;
            border-radius: 10px;
            box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3);
            display: flex;
            align-items: center;
            gap: 10px;
            transform: translateX(120%);
            transition: transform 0.4s ease;
            z-index: 1000;
            border: 1px solid rgba(0, 204, 255, 0.4);
        }
         
        .notification.warning {
            background: rgba(100, 60, 0, 0.9);
            color: #ffcc00;
            border-color: rgba(255, 204, 0, 0.4);
        }
         
        .notification.show {
            transform: translateX(0);
        }
         
        .filter-info {
            background: rgba(0, 40, 80, 0.5);
            border-radius: 8px;
            padding: 12px;
            margin-top: 15px;
            font-size: 0.9rem;
            border-left: 3px solid #00ccff;
            display: flex;
            align-items: center;
            gap: 10px;
            color: #fff;
        }
         
        .unique-info {
            background: rgba(255, 204, 0, 0.15);
            border-left-color: #ffcc00;
        }
         
        /* 重复IP列表样式 */
        .duplicate-ips-container {
            background: rgba(150, 50, 50, 0.3);
            border: 1px solid rgba(255, 100, 100, 0.4);
            border-radius: 12px;
            margin-top: 20px;
            overflow: hidden;
            max-height: 0;
            transition: max-height 0.4s ease;
        }
         
        .duplicate-ips-container.show {
            max-height: 500px;
        }
         
        .duplicate-ips-header {
            padding: 10px 15px;
            display: flex;
            justify-content: space-between;
            align-items: center;
            cursor: pointer;
            background: rgba(180, 60, 60, 0.4);
            color: #fff;
        }
         
        .duplicate-ips-content {
            max-height: 200px;
            overflow-y: auto;
            padding: 10px;
        }
         
        .duplicate-ip-item {
            padding: 8px 15px;
            background: rgba(180, 60, 60, 0.3);
            border-radius: 8px;
            margin-bottom: 8px;
            display: flex;
            justify-content: space-between;
            align-items: center;
            color: #fff;
        }
         
        .duplicate-count {
            background: rgba(255, 100, 100, 0.5);
            border-radius: 12px;
            padding: 2px 8px;
            font-size: 0.8rem;
        }

        /* 按钮分组间距 */
        .action-buttons {
            display: flex;
            gap: 15px;
            flex-wrap: wrap;
        }

        /* 结果框标题区 */
        .results-header-container {
            display: flex;
            justify-content: space-between;
            align-items: center;
            width: 100%;
            flex-wrap: wrap;
            gap: 15px;
        }

        /* 顶部控制区间距 */
        .top-controls {
            display: flex;
            flex-wrap: wrap;
            justify-content: space-between;
            align-items: center;
            gap: 15px;
            width: 100%;
        }
         
        @media (max-width: 768px) {
            .main-content {
                flex-direction: column;
            }
             
            h1 {
                font-size: 2rem;
            }
             
            .features {
                flex-direction: column;
                align-items: center;
            }
             
            .mode-toggle {
                position: static;
                margin-top: 15px;
                align-self: center;
            }

            .box-header {
                flex-direction: column;
                align-items: flex-start;
            }

            .action-buttons {
                width: 100%;
                justify-content: space-between;
                margin-top: 10px;
            }
            
            .copy-btn {
                width: 100%;
                margin-top: 10px;
            }
        }
    </style>
</head>
<body>
    <div class="container">
        <header>
            <h1><i class="fas fa-network-wired"></i> IP与域名提取工具</h1>
            <p class="subtitle">从文本中智能提取IP地址和域名,提供多种过滤模式与重复IP查看功能</p>
             
            <div class="mode-toggle" id="modeToggle">
                <div class="tooltip">切换IP去重模式(唯一IP/传统去重)</div>
                <div class="mode-indicator" id="modeIndicator"></div>
                <span>唯一IP模式</span>
            </div>
             
            <div class="features">
                <div class="feature"><i class="fas fa-check-circle"></i> 智能域名识别</div>
                <div class="feature"><i class="fas fa-filter"></i> IP过滤选项</div>
                <div class="feature"><i class="fas fa-eye"></i> 查看重复IP</div>
                <div class="feature"><i class="fas fa-copy"></i> 一键复制</div>
            </div>
        </header>
         
        <div class="main-content">
            <div class="input-section">
                <h2 class="section-title"><i class="fas fa-paste"></i> 粘贴文本内容</h2>
                <textarea id="inputText" placeholder="在此处粘贴包含IP地址和域名的文本...">访问我们的网站:www.example.com 或 example.org
服务器IP:192.168.1.1 和 10.0.0.1
测试域名:sub.domain.co.uk, another.test.com
重复IP:42.236.17.33 和 42.236.17.33
其他IP:111.225.149.56, 182.98.61.12, 38.207.178.220

测试误识别情况:
文件:202408.rar (不应被识别为域名)
文件:report2024.pdf (不应被识别)
合法域名:123domain.com (应该被识别)

更多重复测试:
192.168.1.1 再次出现
10.0.0.1 和 10.0.0.1 是重复的
42.236.17.33 第三次出现</textarea>
                 
                <div class="filter-info unique-info">
                    <i class="fas fa-exclamation-triangle"></i>
                    <span>唯一IP模式:重复的IP将完全移除,只保留出现一次的IP地址</span>
                </div>
                 
                <div class="button-group">
                    <button id="extractBtn" class="btn btn-primary">
                        <i class="fas fa-magic"></i> 提取IP和域名
                    </button>
                    <button id="clearBtn" class="btn btn-secondary">
                        <i class="fas fa-trash-alt"></i> 清除内容
                    </button>
                </div>
            </div>
             
            <div class="output-section">
                <div class="ip-results">
                    <div class="box-header">
                        <div class="results-header-container">
                            <h2 class="section-title"><i class="fas fa-globe"></i> IP地址 <span id="ipCount" class="counter">0</span></h2>
                            
                            <div class="action-buttons">
                                <button id="showDuplicatesBtn" class="copy-btn btn-orange">
                                    <i class="fas fa-eye"></i> 显示重复IP
                                </button>
                                <button id="copyIpBtn" class="copy-btn">
                                    <i class="fas fa-copy"></i> 复制所有
                                </button>
                            </div>
                        </div>
                    </div>
                    
                    <div class="results-box">
                        <div id="ipResults" class="results-content">
                            <div class="empty-message">提取的IP地址将显示在这里<br><small>重复IP将被完全移除</small></div>
                        </div>
                    </div>
                    
                    <!-- 重复IP列表容器 -->
                    <div id="duplicateIpsContainer" class="duplicate-ips-container">
                        <div class="duplicate-ips-header">
                            <span><i class="fas fa-exclamation-circle"></i> 被过滤的重复IP地址</span>
                            <span id="duplicateCount" class="duplicate-count">0个重复</span>
                        </div>
                        <div id="duplicateIpsContent" class="duplicate-ips-content">
                            <div class="empty-message">没有重复IP地址</div>
                        </div>
                    </div>
                </div>
                 
                <div class="domain-results">
                    <div class="box-header">
                        <div class="top-controls">
                            <h2 class="section-title"><i class="fas fa-server"></i> 域名 <span id="domainCount" class="counter">0</span></h2>
                            <button id="copyDomainBtn" class="copy-btn">
                                <i class="fas fa-copy"></i> 复制所有域名
                            </button>
                        </div>
                    </div>
                    <div class="results-box">
                        <div id="domainResults" class="results-content">
                            <div class="empty-message">提取的域名将显示在这里<br><small>保留唯一的域名</small></div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
     
    <div id="notification" class="notification">
        <i class="fas fa-check-circle"></i>
        <span id="notificationText">已复制到剪贴板!</span>
    </div>
     
    <script>
        document.addEventListener('DOMContentLoaded', function() {
            // DOM元素
            const inputText = document.getElementById('inputText');
            const extractBtn = document.getElementById('extractBtn');
            const clearBtn = document.getElementById('clearBtn');
            const ipResults = document.getElementById('ipResults');
            const domainResults = document.getElementById('domainResults');
            const copyIpBtn = document.getElementById('copyIpBtn');
            const copyDomainBtn = document.getElementById('copyDomainBtn');
            const ipCount = document.getElementById('ipCount');
            const domainCount = document.getElementById('domainCount');
            const notification = document.getElementById('notification');
            const notificationText = document.getElementById('notificationText');
            const modeToggle = document.getElementById('modeToggle');
            const modeIndicator = document.getElementById('modeIndicator');
            const showDuplicatesBtn = document.getElementById('showDuplicatesBtn');
            const duplicateIpsContainer = document.getElementById('duplicateIpsContainer');
            const duplicateIpsContent = document.getElementById('duplicateIpsContent');
            const duplicateCount = document.getElementById('duplicateCount');
             
            let uniqueMode = true; // 默认开启唯一IP模式
            let duplicatesMap = new Map(); // 存储重复IP及其出现次数
            let showDuplicates = false; // 是否显示重复IP列表
             
            // 切换IP处理模式
            modeToggle.addEventListener('click', function() {
                uniqueMode = !uniqueMode;
                if (uniqueMode) {
                    modeIndicator.classList.remove('off');
                    modeToggle.querySelector('span').textContent = '唯一IP模式';
                    showNotification('唯一IP模式:完全移除重复IP', false);
                } else {
                    modeIndicator.classList.add('off');
                    modeToggle.querySelector('span').textContent = '传统去重模式';
                    showNotification('传统去重模式:重复IP保留一个实例', true);
                }
                
                // 隐藏重复IP列表
                showDuplicates = false;
                duplicateIpsContainer.classList.remove('show');
                showDuplicatesBtn.innerHTML = '<i class="fas fa-eye"></i> 显示重复IP';
                
                // 如果有文本内容,重新运行提取
                if (inputText.value.trim()) {
                    extractBtn.click();
                }
            });
            
            // 切换显示重复IP列表
            showDuplicatesBtn.addEventListener('click', function() {
                showDuplicates = !showDuplicates;
                
                if (showDuplicates) {
                    duplicateIpsContainer.classList.add('show');
                    this.innerHTML = '<i class="fas fa-eye-slash"></i> 隐藏重复IP';
                } else {
                    duplicateIpsContainer.classList.remove('show');
                    this.innerHTML = '<i class="fas fa-eye"></i> 显示重复IP';
                }
            });
             
            // 提取IP和域名
            extractBtn.addEventListener('click', function() {
                const text = inputText.value;
                 
                if (!text.trim()) {
                    showNotification('请先输入文本内容', true);
                    return;
                }
                 
                // 提取IP地址 (IPv4格式)
                const ipRegex = /\b(?:\d{1,3}\.){3}\d{1,3}\b/g;
                const ipMatches = text.match(ipRegex) || [];
                 
                // 重置重复IP映射
                duplicatesMap = new Map();
                
                // 按模式处理IP
                let uniqueIPs;
                if (uniqueMode) {
                    // 唯一IP模式:完全移除重复IP
                    const ipCountMap = new Map();
                    
                    // 计数每个IP出现的次数
                    ipMatches.forEach(ip => {
                        ipCountMap.set(ip, (ipCountMap.get(ip) || 0) + 1); // 修复此处变量名错误
                    });
                    
                    // 只保留出现一次的唯一IP
                    uniqueIPs = ipMatches.filter(ip => ipCountMap.get(ip) === 1);
                    
                    // 收集重复IP及其出现次数
                    ipCountMap.forEach((count, ip) => {
                        if (count > 1) {
                            duplicatesMap.set(ip, count);
                        }
                    });
                } else {
                    // 传统模式:去重保留唯一IP
                    uniqueIPs = [...new Set(ipMatches)];
                    
                    // 在传统模式下也收集重复IP信息用于显示
                    const ipCountMap = new Map();
                    ipMatches.forEach(ip => {
                        ipCountMap.set(ip, (ipCountMap.get(ip) || 0) + 1);
                    });
                    
                    ipCountMap.forEach((count, ip) => {
                        if (count > 1) {
                            duplicatesMap.set(ip, count);
                        }
                    });
                }
                 
                // 更新重复IP列表
                updateDuplicateIPsList();
                 
                // 增强版域名提取 - 避免误识别文件名
                // 匹配标准域名格式,排除纯数字前缀的情况
                const domainRegex = /\b(?:[a-z][a-z0-9-]*\.)+[a-z]{2,}\b/gi;
                const rawDomains = text.match(domainRegex) || [];
                 
                // 进一步过滤结果:排除纯数字前缀的"域名"(如202408.rar)
                const domains = [...new Set(rawDomains.filter(domain => {
                    // 获取域名第一部分(排除TLD)
                    const parts = domain.split('.');
                    const mainPart = parts.slice(0, -1).join('');
                     
                    // 如果主要部分只包含数字,则排除(很可能是文件名)
                    return !/^\d+$/.test(mainPart);
                }))];
                 
                // 显示结果
                displayResults(uniqueIPs, ipResults, ipCount, 'ip', ipMatches);
                displayResults(domains, domainResults, domainCount, 'domain');
            });
             
            // 更新重复IP列表
            function updateDuplicateIPsList() {
                duplicateIpsContent.innerHTML = '';
                
                if (duplicatesMap.size === 0) {
                    duplicateIpsContent.innerHTML = '<div class="empty-message">没有重复IP地址</div>';
                    duplicateCount.textContent = '0个重复';
                    return;
                }
                
                duplicateCount.textContent = `${duplicatesMap.size}个重复`;
                
                // 按重复次数排序(从高到低)
                const sortedDuplicates = [...duplicatesMap.entries()]
                    .sort((a, b) => b[1] - a[1]);
                
                sortedDuplicates.forEach(([ip, count]) => {
                    const duplicateItem = document.createElement('div');
                    duplicateItem.className = 'duplicate-ip-item';
                    duplicateItem.innerHTML = `
                        <span>${ip}</span>
                        <div class="duplicate-count">出现 ${count} 次</div>
                    `;
                    duplicateIpsContent.appendChild(duplicateItem);
                });
            }
             
            // 显示结果函数
            function displayResults(items, container, counter, type, originalItems = []) {
                container.innerHTML = '';
                 
                if (items.length === 0) {
                    container.innerHTML = `<div class="empty-message">未找到${type === 'ip' ? 'IP地址' : '域名'}</div>`;
                    counter.textContent = '0';
                    counter.className = 'counter';
                    return;
                }
                 
                counter.textContent = items.length;
                
                // 添加警告样式如果是IP模式且有移除
                if (type === 'ip' && uniqueMode && originalItems.length > items.length) {
                    counter.className = 'counter warning';
                } else {
                    counter.className = 'counter';
                }
                 
                items.forEach(item => {
                    const resultItem = document.createElement('div');
                    resultItem.className = 'result-item';
                    
                    // 标记重复项(在传统模式下)
                    const isDuplicate = type === 'ip' && !uniqueMode && 
                                      originalItems.filter(ip => ip === item).length > 1;
                    
                    if (isDuplicate) {
                        resultItem.classList.add('duplicate');
                    }
                    
                    resultItem.innerHTML = `
                        <span>${item}</span>
                        <i class="fas fa-copy copy-icon" data-value="${item}"></i>
                    `;
                    container.appendChild(resultItem);
                });
                 
                // 添加单个条目的复制功能
                container.querySelectorAll('.copy-icon').forEach(icon => {
                    icon.addEventListener('click', function() {
                        const value = this.getAttribute('data-value');
                        copyToClipboard(value, '已复制: ' + value);
                    });
                });
            }
             
            // 复制IP地址
            copyIpBtn.addEventListener('click', function() {
                const ips = Array.from(ipResults.querySelectorAll('.result-item span'))
                    .map(span => span.textContent)
                    .join('\n');
                 
                if (ips) {
                    copyToClipboard(ips, '已复制所有IP地址');
                } else {
                    showNotification('没有可复制的IP地址', true);
                }
            });
             
            // 复制域名
            copyDomainBtn.addEventListener('click', function() {
                const domains = Array.from(domainResults.querySelectorAll('.result-item span'))
                    .map(span => span.textContent)
                    .join('\n');
                 
                if (domains) {
                    copyToClipboard(domains, '已复制所有域名');
                } else {
                    showNotification('没有可复制的域名', true);
                }
            });
             
            // 清除内容
            clearBtn.addEventListener('click', function() {
                inputText.value = '';
                ipResults.innerHTML = '<div class="empty-message">提取的IP地址将显示在这里<br><small>重复IP将被完全移除</small></div>';
                domainResults.innerHTML = '<div class="empty-message">提取的域名将显示在这里<br><small>保留唯一的域名</small></div>';
                ipCount.textContent = '0';
                domainCount.textContent = '0';
                ipCount.className = 'counter';
                domainCount.className = 'counter';
                
                // 重置重复IP列表
                duplicatesMap = new Map();
                updateDuplicateIPsList();
                showDuplicates = false;
                duplicateIpsContainer.classList.remove('show');
                showDuplicatesBtn.innerHTML = '<i class="fas fa-eye"></i> 显示重复IP';
            });
             
            // 复制到剪贴板函数
            function copyToClipboard(text, message) {
                navigator.clipboard.writeText(text).then(() => {
                    showNotification(message, false);
                }).catch(err => {
                    showNotification('复制失败: ' + err, true);
                });
            }
             
            // 显示通知
            function showNotification(message, isWarning) {
                notificationText.textContent = message;
                notification.className = 'notification';
                
                if (isWarning) {
                    notification.classList.add('warning');
                }
                
                notification.classList.add('show');
                 
                setTimeout(() => {
                    notification.classList.remove('show');
                }, 3000);
            }
             
            // 初始化时自动提取一次
            extractBtn.click();
        });
    </script>
</body>
</html>

使用方式:复制代码到HTML在线运行网站运行,或者黏贴到txt上更改后缀为.html后双击运行

相关推荐
小*-^-*九1 天前
php 使用html 生成pdf word wkhtmltopdf 系列2
pdf·html·php
hashiqimiya1 天前
html实现右上角有个图标,鼠标移动到该位置出现手型,点击会弹出登录窗口。
前端·html
BillKu1 天前
Vue3 中使用 DOMPurify 对渲染动态 HTML 进行安全净化处理
前端·安全·html
BUG创建者2 天前
html获取16个随机颜色并不重复
css·html·css3
DevilSeagull2 天前
JavaScript WebAPI 指南
java·开发语言·javascript·html·ecmascript·html5
面向星辰2 天前
html中css的四种定位方式
前端·css·html
IT利刃出鞘2 天前
HTML--最简的二级菜单页面
前端·html
yume_sibai2 天前
HTML HTML基础(4)
前端·html
面向星辰2 天前
html音视频和超链接标签,颜色标签
前端·html·音视频
信看2 天前
实用 html 小工具
前端·css·html