php代码|统计蜘蛛|统计ip
时间:2025-04-22 06:42:34 阅读:142
这个代码的功效大概是这个刁样的:
首先创建一个后台文件,或者在你后台文件加入这个代码,要自己写一个按钮按钮ID【show-spider-stats】
PHP
<!-- 新访客统计开始 -->
<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();
}
?>
网友评论