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

发布于:2025-07-13 ⋅ 阅读:(14) ⋅ 点赞:(0)

最近在干活的时候发现一个小工具,用于提取防火墙、态感等设备日志中的恶意域名和IP地址,并且带有自动去重、一键去重等功能,极大程度上提高了工作效率,豪用!
这是原文地址:
https://mp.weixin.qq.com/s/irM4e7fcc-iiPRwfJ5lw_w
下面是我改良之后的版本,新增了两个功能点
在这里插入图片描述
1、处理模式分为两个:
唯一IP模式:完全移除重复IP,仅保留出现一次的IP,这个可以用来对照防火墙实际封禁IP与每日记录的封禁名单有什么差别。
传统去重模式:保留重复IP的一个实例。
2、重复IP可视化
被过滤的IP以独立列表折叠展示,支持展开/收起。
重复次数按数值排序(从高到低),便于快速定位高频重复项。

<!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后双击运行


网站公告

今日签到

点亮在社区的每一天
去签到