php代码|统计蜘蛛|统计ip
时间:2025-04-22 06:42:34 阅读:45
这个代码的功效大概是这个刁样的:
首先创建一个后台文件,或者在你后台文件加入这个代码,要自己写一个按钮按钮ID【show-spider-stats】
<!-- 新访客统计开始 --> <style> :root { --primary-color: #4361ee; --secondary-color: #3f37c9; --accent-color: #4cc9f0; --light-color: #f8f9fa; --dark-color: #212529; --success-color: #4bb543; --warning-color: #f8961e; --danger-color: #ef233c; --border-radius: 8px; --box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15); --transition: all 0.3s ease; } .spider-stats-overlay { position: fixed; top: 0; left: 0; right: 0; bottom: 0; background-color: rgba(0, 0, 0, 0.5); backdrop-filter: blur(5px); display: none; z-index: 9000; opacity: 0; transition: opacity 0.3s ease; } .spider-stats-popup { position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%) scale(0.9); width: 90%; max-width: 1200px; height: 90vh; max-height: 90vh; background-color: white; border-radius: var(--border-radius); box-shadow: var(--box-shadow); overflow: hidden; display: flex; flex-direction: column; opacity: 0; transition: all 0.3s ease; z-index: 9001; } .spider-stats-popup.active { opacity: 1; transform: translate(-50%, -50%) scale(1); } .spider-stats-overlay.active { display: block; opacity: 1; } .popup-header { padding: 15px 20px; background: linear-gradient(135deg, var(--primary-color), var(--secondary-color)); color: white; display: flex; justify-content: space-between; align-items: center; } .popup-title { margin: 0; font-size: 1.5rem; font-weight: 600; } .close-btn { background: none; border: none; color: white; font-size: 1.5rem; cursor: pointer; transition: var(--transition); } .close-btn:hover { transform: rotate(90deg); } .popup-content { padding: 20px; overflow-y: auto; flex: 1; display: flex; flex-direction: column; } .table-container { flex: 1; overflow-y: auto; margin-bottom: 20px; } .view-tabs { display: flex; border-bottom: 2px solid #e9ecef; margin-bottom: 20px; } .view-tab { padding: 12px 25px; cursor: pointer; background-color: transparent; border: none; border-bottom: 3px solid transparent; font-weight: 500; color: #6c757d; transition: var(--transition); } .view-tab.active { color: var(--primary-color); border-bottom-color: var(--primary-color); } .view-tab:not(.active):hover { color: var(--secondary-color); } .view-content { display: none; flex: 1; flex-direction: column; } .view-content.active { display: flex; animation: fadeIn 0.3s ease; } @keyframes fadeIn { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } } .filter-bar { display: flex; flex-wrap: wrap; gap: 10px; margin-bottom: 20px; align-items: center; background-color: #f8f9fa; padding: 15px; border-radius: var(--border-radius); } .filter-control { flex: 1 1 200px; } .filter-control select, .filter-control input { width: 100%; padding: 10px 15px; border: 1px solid #ced4da; border-radius: var(--border-radius); transition: var(--transition); } .filter-control select:focus, .filter-control input:focus { border-color: var(--accent-color); outline: none; box-shadow: 0 0 0 3px rgba(76, 201, 240, 0.2); } .btn { padding: 10px 20px; border: none; border-radius: var(--border-radius); cursor: pointer; font-weight: 500; transition: var(--transition); display: inline-flex; align-items: center; gap: 8px; } .btn-primary { background-color: var(--primary-color); color: white; } .btn-primary:hover { background-color: var(--secondary-color); transform: translateY(-2px); } .btn-outline { background-color: transparent; border: 1px solid var(--primary-color); color: var(--primary-color); } .btn-outline:hover { background-color: rgba(67, 97, 238, 0.1); } .btn-danger { background-color: var(--danger-color); color: white; } .btn-danger:hover { background-color: #d90429; } .btn-success { background-color: var(--success-color); color: white; } .btn-success.active { background-color: #3a9a2e; } .data-table { width: 100%; border-collapse: separate; border-spacing: 0; } .data-table th { background-color: #f1f3f5; color: #495057; font-weight: 600; padding: 12px 15px; text-align: left; position: sticky; top: 0; } .data-table td { padding: 12px 15px; border-bottom: 1px solid #e9ecef; vertical-align: middle; } .data-table tr:last-child td { border-bottom: none; } .data-table tr:hover td { background-color: #f8f9fa; } .data-table td.referer-cell { cursor: pointer; position: relative; } .data-table td.referer-cell:hover { background-color: #e9f5ff !important; } .copy-tooltip { position: absolute; background-color: rgba(0, 0, 0, 0.7); color: white; padding: 4px 8px; border-radius: 4px; font-size: 12px; z-index: 100; top: -30px; left: 50%; transform: translateX(-50%); white-space: nowrap; } .highlight-row { background-color: rgba(76, 201, 240, 0.1) !important; } .total-row { background-color: rgba(67, 97, 238, 0.1); font-weight: 600; } .pagination { display: flex; justify-content: center; gap: 8px; margin-top: 20px; flex-wrap: wrap; } .page-btn { min-width: 40px; padding: 8px 12px; border: 1px solid #dee2e6; background-color: white; color: var(--primary-color); border-radius: 4px; cursor: pointer; transition: var(--transition); text-align: center; } .page-btn.first-page, .page-btn.last-page { min-width: 60px; } .page-btn:hover:not(.disabled) { background-color: #f1f3f5; } .page-btn.active { background-color: var(--primary-color); color: white; border-color: var(--primary-color); } .page-btn.disabled { opacity: 0.6; cursor: not-allowed; } .loader { display: inline-block; width: 20px; height: 20px; border: 3px solid rgba(255,255,255,0.3); border-radius: 50%; border-top-color: white; animation: spin 1s ease-in-out infinite; } @keyframes spin { to { transform: rotate(360deg); } } @media (max-width: 768px) { .filter-bar { flex-direction: column; align-items: stretch; } .filter-control { flex: 1 1 100%; } .view-tab { padding: 10px 15px; font-size: 0.9rem; } .data-table th, .data-table td { padding: 8px 10px; font-size: 0.9rem; } } </style> <div class="spider-stats-overlay" id="spider-stats-overlay"></div> <div class="spider-stats-popup" id="spider-stats-popup"> <div class="popup-header"> <h2 class="popup-title">蜘蛛访问统计</h2> <button class="close-btn" id="close-popup">×</button> </div> <div class="popup-content"> <div class="view-tabs"> <button class="view-tab active" data-view="detail"> <i class="fas fa-list"></i> 访问详情 </button> <button class="view-tab" data-view="stats"> <i class="fas fa-chart-bar"></i> 统计概览 </button> </div> <div class="view-content active" id="detail-view"> <div class="filter-bar"> <div class="filter-control"> <select id="spider-filter"> <option value="">所有蜘蛛类型</option> </select> </div> <div class="filter-control"> <input type="text" id="search-input" placeholder="搜索关键词..."> </div> <button id="search-btn" class="btn btn-primary"> <i class="fas fa-search"></i> 搜索 </button> <button id="reset-btn" class="btn btn-outline"> <i class="fas fa-undo"></i> 重置 </button> <button id="key-domain-btn" class="btn btn-success"> <i class="fas fa-star"></i> 关键域名 </button> <button id="clear-btn" class="btn btn-danger"> <i class="fas fa-trash"></i> 清空 </button> </div> <div class="table-container"> <table class="data-table" id="detail-table"> <thead> <tr> <th>ID</th> <th>访问时间</th> <th>蜘蛛类型</th> <th>IP地址</th> <th>访问URL</th> <th>来路URL</th> </tr> </thead> <tbody id="detail-table-body"></tbody> </table> </div> <div class="pagination" id="detail-pagination"></div> </div> <div class="view-content" id="stats-view"> <div class="table-container"> <table class="data-table" id="stats-table"> <thead> <tr> <th>蜘蛛类型</th> <th>今天</th> <th>昨天</th> <th>本周</th> <th>上周</th> <th>近30天</th> <th>总计</th> </tr> </thead> <tbody id="stats-table-body"></tbody> </table> </div> </div> </div> </div> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css"> <script> document.addEventListener('DOMContentLoaded', function() { // 获取所有需要的元素 const popup = document.getElementById('spider-stats-popup'); const overlay = document.getElementById('spider-stats-overlay'); const closeBtn = document.getElementById('close-popup'); const showBtn = document.getElementById('show-spider-stats'); const detailTableBody = document.getElementById('detail-table-body'); const statsTableBody = document.getElementById('stats-table-body'); const detailPagination = document.getElementById('detail-pagination'); const spiderFilter = document.getElementById('spider-filter'); const searchInput = document.getElementById('search-input'); const searchBtn = document.getElementById('search-btn'); const resetBtn = document.getElementById('reset-btn'); const clearBtn = document.getElementById('clear-btn'); const keyDomainBtn = document.getElementById('key-domain-btn'); const viewTabs = document.querySelectorAll('.view-tab'); const viewContents = document.querySelectorAll('.view-content'); // 全局变量 let currentPage = 1; const itemsPerPage = 15; let showKeyDomainsOnly = false; let currentView = 'detail'; let spiderTypes = []; let updateInterval; // 打开弹窗 function openPopup() { document.body.style.overflow = 'hidden'; overlay.style.display = 'block'; setTimeout(() => { overlay.classList.add('active'); popup.classList.add('active'); }, 10); loadDetailData(1); startAutoRefresh(); } // 关闭弹窗 function closePopup() { overlay.classList.remove('active'); popup.classList.remove('active'); document.body.style.overflow = ''; clearInterval(updateInterval); // 完全移除遮罩层 setTimeout(() => { overlay.style.display = 'none'; }, 300); } // 加载详情数据(支持静默模式) function loadDetailData(page, silent = false) { currentPage = page; const spiderType = spiderFilter.value; const searchText = searchInput.value.toLowerCase(); if (!silent) { detailTableBody.innerHTML = `<tr><td colspan="6" style="text-align: center;"><div class="loader"></div> 加载中...</td></tr>`; } let url = `/wg/hongyu/zhizhu.php?action=getLogs&page=${page}&perPage=${itemsPerPage}`; if (spiderType) url += `&spider=${encodeURIComponent(spiderType)}`; if (searchText) url += `&search=${encodeURIComponent(searchText)}`; if (showKeyDomainsOnly) url += `&keyDomains=1`; fetch(url) .then(response => response.json()) .then(data => { detailTableBody.innerHTML = ''; spiderTypes = []; if (data.logs.length === 0) { detailTableBody.innerHTML = `<tr><td colspan="6" style="text-align: center;">没有找到匹配的记录</td></tr>`; return; } data.logs.forEach((log, index) => { const row = document.createElement('tr'); if (log.isKeyDomain) row.classList.add('highlight-row'); row.innerHTML = ` <td>${(page - 1) * itemsPerPage + index + 1}</td> <td>${log.time}</td> <td>${log.spider}</td> <td><a href="https://m.ip138.com/iplookup.asp?ip=${log.ip}" target="_blank">${log.ip}</a></td> <td><a href="${log.url}" target="_blank" title="${log.url}">${shortenText(log.url, 40)}</a></td> `; const refererCell = document.createElement('td'); refererCell.className = 'referer-cell'; refererCell.title = log.referer; refererCell.textContent = shortenText(log.referer, 40); refererCell.addEventListener('click', function() { copyToClipboard(log.referer); showCopiedTooltip(this); }); row.appendChild(refererCell); detailTableBody.appendChild(row); if (!spiderTypes.includes(log.spider)) { spiderTypes.push(log.spider); } }); updateSpiderFilter(); renderPagination(data.totalPages, page); if (!silent) { detailTableBody.scrollIntoView({ behavior: 'smooth' }); } }) .catch(error => { if (!silent) { detailTableBody.innerHTML = `<tr><td colspan="6" style="text-align: center; color: var(--danger-color);">加载失败: ${error.message}</td></tr>`; } }); } // 加载统计数据(支持静默模式) function loadStatsData(silent = false) { if (!silent) { statsTableBody.innerHTML = `<tr><td colspan="7" style="text-align: center;"><div class="loader"></div> 加载中...</td></tr>`; } fetch('/wg/hongyu/zhizhu.php?action=getStats') .then(response => response.json()) .then(data => { statsTableBody.innerHTML = ''; if (data.length === 0) { statsTableBody.innerHTML = `<tr><td colspan="7" style="text-align: center;">没有统计数据</td></tr>`; return; } data.forEach(item => { const row = document.createElement('tr'); if (item.engine === '总计') row.classList.add('total-row'); if (item.engine === '关键域名') row.classList.add('highlight-row'); row.innerHTML = ` <td>${item.engine}</td> <td>${item.today}</td> <td>${item.yesterday}</td> <td>${item.thisWeek}</td> <td>${item.lastWeek}</td> <td>${item.last30Days}</td> <td>${item.total}</td> `; statsTableBody.appendChild(row); }); }) .catch(error => { if (!silent) { statsTableBody.innerHTML = `<tr><td colspan="7" style="text-align: center; color: var(--danger-color);">加载失败: ${error.message}</td></tr>`; } }); } // 复制到剪贴板 function copyToClipboard(text) { const textarea = document.createElement('textarea'); textarea.value = text; document.body.appendChild(textarea); textarea.select(); document.execCommand('copy'); document.body.removeChild(textarea); } // 显示复制提示 function showCopiedTooltip(element) { const existingTooltip = document.querySelector('.copy-tooltip'); if (existingTooltip) { existingTooltip.remove(); } const tooltip = document.createElement('div'); tooltip.className = 'copy-tooltip'; tooltip.textContent = '已复制!'; const rect = element.getBoundingClientRect(); tooltip.style.left = `${rect.left + window.scrollX + rect.width/2}px`; tooltip.style.top = `${rect.top + window.scrollY - 30}px`; document.body.appendChild(tooltip); setTimeout(() => { tooltip.remove(); }, 1000); } // 更新蜘蛛类型筛选 function updateSpiderFilter() { const currentValue = spiderFilter.value; spiderFilter.innerHTML = '<option value="">所有蜘蛛类型</option>'; spiderTypes.forEach(type => { const option = document.createElement('option'); option.value = type; option.textContent = type; if (type === currentValue) option.selected = true; spiderFilter.appendChild(option); }); } // 渲染分页 function renderPagination(totalPages, currentPage) { detailPagination.innerHTML = ''; if (totalPages <= 1) return; let startPage = Math.max(1, currentPage - 2); let endPage = Math.min(totalPages, currentPage + 2); if (endPage - startPage < 4) { if (currentPage < 3) { endPage = Math.min(5, totalPages); } else { startPage = Math.max(1, endPage - 4); } } const firstBtn = document.createElement('button'); firstBtn.className = `page-btn first-page ${currentPage === 1 ? 'disabled' : ''}`; firstBtn.textContent = '首页'; if (currentPage !== 1) { firstBtn.addEventListener('click', () => loadDetailData(1)); } detailPagination.appendChild(firstBtn); const prevBtn = document.createElement('button'); prevBtn.className = `page-btn ${currentPage === 1 ? 'disabled' : ''}`; prevBtn.innerHTML = '<i class="fas fa-chevron-left"></i> 上一页'; if (currentPage !== 1) { prevBtn.addEventListener('click', () => loadDetailData(currentPage - 1)); } detailPagination.appendChild(prevBtn); for (let i = startPage; i <= endPage; i++) { const pageBtn = document.createElement('button'); pageBtn.className = `page-btn ${i === currentPage ? 'active' : ''}`; pageBtn.textContent = i; if (i !== currentPage) { pageBtn.addEventListener('click', () => loadDetailData(i)); } detailPagination.appendChild(pageBtn); } const nextBtn = document.createElement('button'); nextBtn.className = `page-btn ${currentPage === totalPages ? 'disabled' : ''}`; nextBtn.innerHTML = '下一页 <i class="fas fa-chevron-right"></i>'; if (currentPage !== totalPages) { nextBtn.addEventListener('click', () => loadDetailData(currentPage + 1)); } detailPagination.appendChild(nextBtn); const lastBtn = document.createElement('button'); lastBtn.className = `page-btn last-page ${currentPage === totalPages ? 'disabled' : ''}`; lastBtn.textContent = '尾页'; if (currentPage !== totalPages) { lastBtn.addEventListener('click', () => loadDetailData(totalPages)); } detailPagination.appendChild(lastBtn); } // 文本截断 function shortenText(text, maxLength) { return text.length > maxLength ? text.substring(0, maxLength) + '...' : text; } // 搜索功能 searchBtn.addEventListener('click', () => loadDetailData(1)); searchInput.addEventListener('keypress', (e) => { if (e.key === 'Enter') loadDetailData(1); }); // 重置筛选 resetBtn.addEventListener('click', function() { spiderFilter.value = ''; searchInput.value = ''; showKeyDomainsOnly = false; keyDomainBtn.classList.remove('active'); keyDomainBtn.innerHTML = '<i class="fas fa-star"></i> 关键域名'; loadDetailData(1); }); // 关键域名筛选 keyDomainBtn.addEventListener('click', function() { showKeyDomainsOnly = !showKeyDomainsOnly; this.classList.toggle('active'); this.innerHTML = showKeyDomainsOnly ? '<i class="fas fa-check"></i> 显示全部' : '<i class="fas fa-star"></i> 关键域名'; loadDetailData(1); }); // 清空日志 clearBtn.addEventListener('click', function() { if (confirm('确定要清空所有日志记录吗?此操作不可撤销!')) { this.innerHTML = '<div class="loader"></div> 处理中...'; this.disabled = true; fetch('/wg/hongyu/zhizhu.php?action=clearLogs') .then(response => response.json()) .then(data => { if (data.success) { alert('日志已清空'); loadDetailData(1); loadStatsData(); } else { alert('清空失败: ' + (data.error || '未知错误')); } }) .finally(() => { this.innerHTML = '<i class="fas fa-trash"></i> 清空'; this.disabled = false; }); } }); // 视图切换 viewTabs.forEach(tab => { tab.addEventListener('click', function() { const view = this.dataset.view; currentView = view; viewTabs.forEach(t => t.classList.remove('active')); this.classList.add('active'); viewContents.forEach(content => { if (content.id === `${view}-view`) { content.classList.add('active'); if (view === 'stats' && statsTableBody.children.length === 0) { loadStatsData(); } } else { content.classList.remove('active'); } }); }); }); // 启动自动刷新 function startAutoRefresh() { clearInterval(updateInterval); updateInterval = setInterval(() => { if (popup.classList.contains('active') && !document.hidden) { if (currentView === 'detail') { loadDetailData(currentPage, true); } else { loadStatsData(true); } } }, 5000); } // 事件监听 closeBtn.addEventListener('click', closePopup); overlay.addEventListener('click', closePopup); // 阻止弹窗内部点击事件冒泡 popup.addEventListener('click', function(e) { e.stopPropagation(); }); // 如果您有一个显示按钮,请取消下面的注释并设置正确的ID document.getElementById('show-spider-stats').addEventListener('click', openPopup); }); </script> <!-- 新访客统计结束 -->
再创建一个zhizhu.php文件
<?php $logFile = '/www/wwwroot/www.chfkw.top/wg/txt/ua.txt'; $keyDomainsFile = '/www/wwwroot/www.chfkw.top/wg/txt/guanjianyuming.txt'; // 获取关键域名列表 function getKeyDomains() { global $keyDomainsFile; if (!file_exists($keyDomainsFile)) return []; $domains = []; $lines = file($keyDomainsFile, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); foreach ($lines as $line) { $line = trim(preg_replace('/【.*?】/', '', $line)); if ($line && strpos($line, '//') !== 0) { $domains[] = strtolower($line); } } return $domains; } // 解析日志行 function parseLogLine($line) { if (!preg_match('/时间:(.*?) 蜘蛛:(.*?) IP:(.*?) UA: (.*?) 链接:(.*?) 来路:(.*)/', $line, $matches)) { return null; } return [ 'time' => $matches[1], 'spider' => $matches[2], 'ip' => $matches[3], 'ua' => $matches[4], 'url' => $matches[5], 'referer' => $matches[6] ]; } // 检查是否关键域名 function isKeyDomain($referer, $keyDomains) { if (empty($keyDomains)) return false; $referer = strtolower($referer); foreach ($keyDomains as $domain) { if (strpos($referer, $domain) !== false) { return true; } } return false; } // 获取时间范围 function getTimeRange($timestamp) { $now = time(); $diff = $now - $timestamp; return [ 'today' => date('Y-m-d', $timestamp) === date('Y-m-d'), 'yesterday' => date('Y-m-d', $timestamp) === date('Y-m-d', strtotime('-1 day')), 'thisWeek' => $timestamp >= strtotime('last Monday'), 'lastWeek' => $timestamp >= strtotime('last Monday -1 week') && $timestamp < strtotime('last Monday'), 'last30Days' => $diff <= 30 * 24 * 3600 ]; } // 主处理逻辑 if ($_SERVER['REQUEST_METHOD'] === 'GET') { $action = $_GET['action'] ?? ''; try { if (!file_exists($logFile)) { throw new Exception('日志文件不存在'); } $logs = file($logFile, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); $logs = array_reverse($logs); // 最新的在前面 $keyDomains = getKeyDomains(); header('Content-Type: application/json'); switch ($action) { case 'getLogs': $page = max(1, intval($_GET['page'] ?? 1)); $perPage = intval($_GET['perPage'] ?? 15); $spiderFilter = $_GET['spider'] ?? ''; $searchText = $_GET['search'] ?? ''; $filterKeyDomains = isset($_GET['keyDomains']); $filteredLogs = []; foreach ($logs as $line) { $log = parseLogLine($line); if (!$log) continue; // 应用筛选条件 $matchSpider = !$spiderFilter || strpos($log['spider'], $spiderFilter) !== false; $matchSearch = !$searchText || stripos($line, $searchText) !== false; $matchKeyDomain = !$filterKeyDomains || isKeyDomain($log['referer'], $keyDomains); if ($matchSpider && $matchSearch && $matchKeyDomain) { $log['isKeyDomain'] = isKeyDomain($log['referer'], $keyDomains); $filteredLogs[] = $log; } } $total = count($filteredLogs); $totalPages = ceil($total / $perPage); $pageLogs = array_slice($filteredLogs, ($page - 1) * $perPage, $perPage); echo json_encode([ 'logs' => $pageLogs, 'total' => $total, 'totalPages' => $totalPages ]); break; case 'getStats': $stats = []; $totalStats = [ 'engine' => '总计', 'today' => 0, 'yesterday' => 0, 'thisWeek' => 0, 'lastWeek' => 0, 'last30Days' => 0, 'total' => 0 ]; // 按蜘蛛类型统计 $spiderStats = []; foreach ($logs as $line) { $log = parseLogLine($line); if (!$log) continue; $timestamp = strtotime($log['time']); if (!$timestamp) continue; $timeRange = getTimeRange($timestamp); $spider = $log['spider']; if (!isset($spiderStats[$spider])) { $spiderStats[$spider] = [ 'today' => 0, 'yesterday' => 0, 'thisWeek' => 0, 'lastWeek' => 0, 'last30Days' => 0, 'total' => 0 ]; } if ($timeRange['today']) $spiderStats[$spider]['today']++; if ($timeRange['yesterday']) $spiderStats[$spider]['yesterday']++; if ($timeRange['thisWeek']) $spiderStats[$spider]['thisWeek']++; if ($timeRange['lastWeek']) $spiderStats[$spider]['lastWeek']++; if ($timeRange['last30Days']) $spiderStats[$spider]['last30Days']++; $spiderStats[$spider]['total']++; // 累加总计 if ($timeRange['today']) $totalStats['today']++; if ($timeRange['yesterday']) $totalStats['yesterday']++; if ($timeRange['thisWeek']) $totalStats['thisWeek']++; if ($timeRange['lastWeek']) $totalStats['lastWeek']++; if ($timeRange['last30Days']) $totalStats['last30Days']++; $totalStats['total']++; } // 格式化蜘蛛统计 foreach ($spiderStats as $engine => $counts) { $stats[] = array_merge(['engine' => $engine], $counts); } // 关键域名统计 if (!empty($keyDomains)) { $keyDomainStats = [ 'engine' => '关键域名', 'today' => 0, 'yesterday' => 0, 'thisWeek' => 0, 'lastWeek' => 0, 'last30Days' => 0, 'total' => 0 ]; foreach ($logs as $line) { $log = parseLogLine($line); if (!$log) continue; if (isKeyDomain($log['referer'], $keyDomains)) { $timestamp = strtotime($log['time']); if (!$timestamp) continue; $timeRange = getTimeRange($timestamp); if ($timeRange['today']) $keyDomainStats['today']++; if ($timeRange['yesterday']) $keyDomainStats['yesterday']++; if ($timeRange['thisWeek']) $keyDomainStats['thisWeek']++; if ($timeRange['lastWeek']) $keyDomainStats['lastWeek']++; if ($timeRange['last30Days']) $keyDomainStats['last30Days']++; $keyDomainStats['total']++; } } $stats[] = $keyDomainStats; } // 添加总计 $stats[] = $totalStats; echo json_encode($stats); break; case 'clearLogs': if (file_put_contents($logFile, '') !== false) { echo json_encode(['success' => true]); } else { echo json_encode(['success' => false, 'error' => '清空日志失败']); } break; default: throw new Exception('无效的操作'); } } catch (Exception $e) { http_response_code(500); echo json_encode(['error' => $e->getMessage()]); } } ?>
最后在你的首页添加记录代码
<?php /*写入访问UA*/ // 定义常见蜘蛛的 UA 关键字,添加了更多国内常见蜘蛛 $spiders = array( "Baiduspider", "Baiduspider-image", "Baiduspider-video", "Baiduspider-news", "Baiduspider-favo", "Googlebot", "360Spider", "Sogou spider", "Sogou web spider", "Sogou inst spider", "YandexBot", "bingbot", "Sosospider", "Bytespider", // 今日头条蜘蛛 "Yisouspider" // 神马搜索蜘蛛 ); // 定义蜘蛛名称转换数组 $spiderNameConversion = array( "Baiduspider" => "百度蜘蛛", "Baiduspider-image" => "百度图片蜘蛛", "Baiduspider-video" => "百度视频蜘蛛", "Baiduspider-news" => "百度新闻蜘蛛", "Baiduspider-favo" => "百度收藏蜘蛛", "Googlebot" => "谷歌蜘蛛", "360Spider" => "360蜘蛛", "Sogou spider" => "搜狗蜘蛛", "Sogou web spider" => "搜狗网页蜘蛛", "Sogou inst spider" => "搜狗图片蜘蛛", "YandexBot" => "Yandex蜘蛛", "bingbot" => "必应蜘蛛", "Sosospider" => "搜搜蜘蛛", "Bytespider" => "今日头条蜘蛛", "Yisouspider" => "神马蜘蛛" ); // 获取用户代理信息 $userAgent = $_SERVER['HTTP_USER_AGENT']; // 初始化蜘蛛名称 $spiderName = "未知"; // 检查是否为已知蜘蛛 foreach ($spiders as $spider) { if (strpos($userAgent, $spider)!== false) { $spiderName = $spider; break; } } // 进行蜘蛛名称转换 if (isset($spiderNameConversion[$spiderName])) { $spiderName = $spiderNameConversion[$spiderName]; } // 获取当前网站的网址 $protocol = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on')? "https://" : "http://"; $host = $_SERVER['HTTP_HOST']; $requestUri = $_SERVER['REQUEST_URI']; $currentUrl = $protocol.$host.$requestUri; // 获取蜘蛛IP地址 $spiderIp = $_SERVER['REMOTE_ADDR']; // 获取 Referer 信息 $referer = isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : "无"; // 尝试根据 User-Agent 推断来路 function inferRefererFromUserAgent($userAgent) { $spiderRules = [ "Baiduspider" => "https://www.baidu.com", "Googlebot" => "https://www.google.com", "360Spider" => "https://www.so.com", "Sogou spider" => "https://www.sogou.com", "bingbot" => "https://www.bing.com", "Bytespider" => "https://www.toutiao.com", "Yisouspider" => "https://www.sm.cn" ]; foreach ($spiderRules as $spider => $refererUrl) { if (strpos($userAgent, $spider)!== false) { return $refererUrl; } } return "无"; } if ($referer === "无") { $referer = inferRefererFromUserAgent($userAgent); } // 记录访问信息,修改格式 $logMessage = "时间:" . date('Y-m-d H:i:s') . " 蜘蛛:" . $spiderName. " IP:" . $spiderIp. " UA: " . $userAgent. " 链接:" . $currentUrl. " 来路:" . $referer. "\n"; // 写入文件 $file = '/www/wwwroot/www.chfkw.top/wg/txt/ua.txt'; try { if (!is_writable($file)) { // 检查文件是否可写 throw new Exception("文件 $file 不可写,请检查文件权限。"); } file_put_contents($file, $logMessage, FILE_APPEND | LOCK_EX); } catch (Exception $e) { echo "写入文件时出现错误: ". $e->getMessage(); } ?>
网友评论