Files
yixiaogao/frontend/index.html

287 lines
16 KiB
HTML
Raw Permalink Normal View History

2025-11-27 18:32:24 +08:00
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>微信公众号文章爬虫系统</title>
<link rel="stylesheet" href="css/style.css">
</head>
<body>
2025-12-02 14:58:52 +08:00
<!-- 头部导航 -->
<header class="top-navbar" style="background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; padding: 15px 0; box-shadow: 0 2px 10px rgba(0,0,0,0.1); position: sticky; top: 0; z-index: 100;">
<div class="navbar-content" style="max-width: 1200px; margin: 0 auto; padding: 0 20px; display: flex; align-items: center; justify-content: space-between;">
<a href="frontend.html" class="logo" style="font-size: 24px; font-weight: bold; text-decoration: none; color: white;">🔍 易搜高</a>
<nav class="nav-menu" style="display: flex; gap: 15px; align-items: center;">
<a href="frontend.html" class="nav-link" style="color: white; text-decoration: none; font-size: 14px; font-weight: 500; padding: 8px 16px; border-radius: 6px; transition: all 0.3s; background: rgba(255, 255, 255, 0.1); border: 1px solid rgba(255, 255, 255, 0.2);" onmouseover="this.style.background='rgba(255, 255, 255, 0.2)'" onmouseout="this.style.background='rgba(255, 255, 255, 0.1)'">首页</a>
<a href="#" class="nav-link" style="color: white; text-decoration: none; font-size: 14px; font-weight: 500; padding: 8px 16px; border-radius: 6px; transition: all 0.3s; background: rgba(255, 255, 255, 0.1); border: 1px solid rgba(255, 255, 255, 0.2);" onmouseover="this.style.background='rgba(255, 255, 255, 0.2)'" onmouseout="this.style.background='rgba(255, 255, 255, 0.1)'">监控中心</a>
<a href="#" class="nav-link" style="color: white; text-decoration: none; font-size: 14px; font-weight: 500; padding: 8px 16px; border-radius: 6px; transition: all 0.3s; background: rgba(255, 255, 255, 0.1); border: 1px solid rgba(255, 255, 255, 0.2);" onmouseover="this.style.background='rgba(255, 255, 255, 0.2)'" onmouseout="this.style.background='rgba(255, 255, 255, 0.1)'">数据分析</a>
<a href="#" class="nav-link" style="color: white; text-decoration: none; font-size: 14px; font-weight: 500; padding: 8px 16px; border-radius: 6px; transition: all 0.3s; background: rgba(255, 255, 255, 0.1); border: 1px solid rgba(255, 255, 255, 0.2);" onmouseover="this.style.background='rgba(255, 255, 255, 0.2)'" onmouseout="this.style.background='rgba(255, 255, 255, 0.1)'">帮助文档</a>
<a href="user-center.html" class="nav-link" id="userCenterLink" style="color: white; text-decoration: none; font-size: 14px; font-weight: 500; padding: 8px 16px; border-radius: 6px; transition: all 0.3s; background: rgba(255, 255, 255, 0.1); border: 1px solid rgba(255, 255, 255, 0.2);" onmouseover="this.style.background='rgba(255, 255, 255, 0.2)'" onmouseout="this.style.background='rgba(255, 255, 255, 0.1)'">👤 用户中心</a>
<a href="login.html" class="nav-link" id="loginLink" style="color: white; text-decoration: none; font-size: 14px; font-weight: 500; padding: 8px 16px; border-radius: 6px; transition: all 0.3s; background: rgba(255, 255, 255, 0.1); border: 1px solid rgba(255, 255, 255, 0.2);" onmouseover="this.style.background='rgba(255, 255, 255, 0.2)'" onmouseout="this.style.background='rgba(255, 255, 255, 0.1)'">🔐 登录</a>
<div id="userMenu" class="user-info" style="display: flex; align-items: center; gap: 10px;"></div>
</nav>
</div>
</header>
2025-11-27 18:32:24 +08:00
<div class="container">
<header class="header">
<h1>🚀 微信公众号文章爬虫系统</h1>
<p class="subtitle">Wechat Official Account Article Crawler</p>
</header>
<div class="main-content">
<!-- 功能选择卡片 -->
<div class="feature-cards">
<div class="card" id="card-homepage">
<div class="card-icon">🏠</div>
<h3>提取公众号主页</h3>
<p>输入文章链接获取公众号主页链接</p>
<button class="btn btn-primary" onclick="showSection('homepage')">进入</button>
</div>
<div class="card" id="card-list">
<div class="card-icon">📋</div>
<h3>获取文章列表</h3>
<p>获取公众号所有文章列表</p>
<button class="btn btn-primary" onclick="showSection('list')">进入</button>
</div>
<div class="card" id="card-batch">
<div class="card-icon">📦</div>
<h3>批量下载文章</h3>
<p>批量下载文章详细内容</p>
<button class="btn btn-primary" onclick="showSection('batch')">进入</button>
</div>
2025-12-02 14:58:52 +08:00
<div class="card" id="card-detail">
2025-11-27 18:32:24 +08:00
<div class="card-icon">📊</div>
2025-12-02 14:58:52 +08:00
<h3>获取文章详情</h3>
<p>获取文章阅读量、点赞数、评论等详细信息</p>
<button class="btn btn-primary" onclick="showSection('detail')">进入</button>
2025-11-27 18:32:24 +08:00
</div>
</div>
<!-- 提取公众号主页区域 -->
<div class="section" id="section-homepage" style="display:none;">
<div class="section-header">
<h2>🏠 提取公众号主页</h2>
<button class="btn btn-secondary" onclick="showSection('home')">返回</button>
</div>
<div class="form-group">
<label>公众号文章链接:</label>
<input type="text" id="homepage-url" placeholder="请输入公众号下任意一篇已发布的文章链接...">
<small>支持公众号文章完整URL无需Cookie即可获取公众号主页链接</small>
</div>
<div class="form-actions">
<button class="btn btn-success" onclick="extractHomepage()">提取主页链接</button>
<button class="btn btn-info" onclick="loadExampleUrl()">查看示例</button>
</div>
<div class="result" id="homepage-result"></div>
</div>
<!-- 获取文章列表区域 -->
<div class="section" id="section-list" style="display:none;">
<div class="section-header">
<h2>📋 获取文章列表</h2>
<button class="btn btn-secondary" onclick="showSection('home')">返回</button>
</div>
<div class="form-group">
<label>Access Token URL</label>
<textarea id="access-token" placeholder="请粘贴从Fiddler获取的完整URL..." rows="4"></textarea>
<small>包含 __biz, uin, key, pass_ticket 等参数的完整URL</small>
</div>
<div class="form-group">
<label>获取页数:</label>
<input type="number" id="pages" value="1" min="1" max="999">
<small>留空表示获取全部</small>
</div>
<div class="form-actions">
<button class="btn btn-success" onclick="getArticleList()">开始获取</button>
</div>
<div class="result" id="list-result"></div>
</div>
<!-- 批量下载区域 -->
<div class="section" id="section-batch" style="display:none;">
<div class="section-header">
<h2>📦 批量下载文章</h2>
<button class="btn btn-secondary" onclick="showSection('home')">返回</button>
</div>
<div class="form-group">
<label>公众号名称或文章链接:</label>
<input type="text" id="official-account" placeholder="请输入公众号名称或任意一篇文章链接...">
</div>
<div class="form-group">
<label class="checkbox-label">
<input type="checkbox" id="batch-save-image"> 保存图片
</label>
<label class="checkbox-label">
<input type="checkbox" id="batch-save-content" checked> 保存内容
</label>
</div>
<div class="form-actions">
<button class="btn btn-success" onclick="batchDownload()">开始批量下载</button>
</div>
<div class="result" id="batch-result"></div>
</div>
2025-12-02 14:58:52 +08:00
<!-- 获取文章详情区域 -->
<div class="section" id="section-detail" style="display:none;">
2025-11-27 18:32:24 +08:00
<div class="section-header">
2025-12-02 14:58:52 +08:00
<h2>📊 获取文章详情</h2>
2025-11-27 18:32:24 +08:00
<button class="btn btn-secondary" onclick="showSection('home')">返回</button>
</div>
2025-12-02 14:58:52 +08:00
<div class="help-text">
<p><strong>💡 功能说明:</strong></p>
<ul>
<li>📈 自动获取公众号所有文章列表</li>
<li>📊 下载每篇文章的阅读量、点赞数、分享数等统计数据</li>
<li>💬 获取文章评论信息(如果有)</li>
<li>📁 保存为TXT格式便于查看和分析</li>
</ul>
<p><strong>⚠️ 注意事项:</strong></p>
<ul>
<li>需要提供有效的Access Token URL包含登录凭证</li>
<li>处理时间较长,请耐心等待</li>
<li>数据将保存在 data/公众号名称/文章详细 目录下</li>
</ul>
2025-11-27 18:32:24 +08:00
</div>
2025-12-02 14:58:52 +08:00
<div class="form-group">
<label>Access Token URL</label>
<textarea id="detail-access-token" placeholder="请粘贴从Fiddler获取的完整URL...\n\n步骤\n1. 在浏览器中登录微信公众号平台\n2. 访问目标公众号主页\n3. 向下滚动加载文章列表\n4. 在Fiddler中找到profile_ext?action=getmsg请求\n5. 复制完整的URL包含__biz、uin、key、pass_ticket等参数" rows="6"></textarea>
<small>示例https://mp.weixin.qq.com/mp/profile_ext?action=getmsg&__biz=...&uin=...&key=...&pass_ticket=...</small>
2025-11-27 18:32:24 +08:00
</div>
2025-12-02 14:58:52 +08:00
<div class="form-group">
<label>获取页数:</label>
<input type="number" id="detail-pages" value="0" min="0" max="999" placeholder="留空或0表示获取全部">
<small>每页约10篇文章留空或输入0表示获取全部文章</small>
</div>
<div class="form-actions">
<button class="btn btn-success" onclick="getArticleDetail()">开始获取</button>
<button class="btn btn-info" onclick="loadDetailExample()">查看示例</button>
</div>
<div class="result" id="detail-result"></div>
</div>
2025-11-27 18:32:24 +08:00
</div>
<footer class="footer">
<p>© 2025 微信公众号文章爬虫系统 | 仅供学习使用</p>
</footer>
</div>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script src="js/app.js"></script>
2025-12-02 14:58:52 +08:00
<script>
// 登录状态管理
function checkLoginStatus() {
// 检查认证数据
const authData = localStorage.getItem('authData') || sessionStorage.getItem('authData');
if (authData) {
try {
const auth = JSON.parse(authData);
const username = auth.user_info && auth.user_info.username ? auth.user_info.username : '用户';
showLoggedInState(username);
} catch (e) {
console.error('解析登录数据失败:', e);
showLoggedOutState();
}
} else {
showLoggedOutState();
}
}
// 显示已登录状态
function showLoggedInState(username) {
const loginLink = document.getElementById('loginLink');
const userMenu = document.getElementById('userMenu');
if (loginLink) loginLink.style.display = 'none';
if (userMenu) {
userMenu.innerHTML = `
<span style="margin-right: 10px;">👋 ${username}</span>
<button onclick="logout()" style="
background: rgba(255, 255, 255, 0.2);
color: white;
border: 1px solid rgba(255, 255, 255, 0.3);
padding: 6px 12px;
border-radius: 4px;
cursor: pointer;
font-size: 13px;
transition: all 0.3s;
" onmouseover="this.style.background='rgba(255, 255, 255, 0.3)'"
onmouseout="this.style.background='rgba(255, 255, 255, 0.2)'">
退出登录
</button>
`;
userMenu.style.display = 'flex';
}
}
// 显示未登录状态
function showLoggedOutState() {
const loginLink = document.getElementById('loginLink');
const userMenu = document.getElementById('userMenu');
if (loginLink) loginLink.style.display = 'inline';
if (userMenu) userMenu.innerHTML = '';
}
// 登出功能
function logout() {
if (confirm('确定要退出登录吗?')) {
// 获取认证数据
const authData = localStorage.getItem('authData') || sessionStorage.getItem('authData');
let token = '';
if (authData) {
try {
const auth = JSON.parse(authData);
token = auth.token || '';
} catch (e) {
console.error('解析token失败:', e);
}
}
// 调用后端登出API
fetch('http://localhost:8080/api/user/logout', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': token ? `Bearer ${token}` : ''
}
}).then(response => {
// 无论API调用成功与否都清除本地数据
localStorage.removeItem('authData');
localStorage.removeItem('isLoggedIn');
localStorage.removeItem('username');
localStorage.removeItem('token');
sessionStorage.removeItem('authData');
sessionStorage.removeItem('userSession');
alert('已成功退出登录!');
window.location.href = 'login.html';
}).catch(error => {
console.error('登出请求失败:', error);
// 即使API调用失败也清除本地数据
localStorage.removeItem('authData');
localStorage.removeItem('isLoggedIn');
localStorage.removeItem('username');
localStorage.removeItem('token');
sessionStorage.removeItem('authData');
sessionStorage.removeItem('userSession');
alert('已成功退出登录!');
window.location.href = 'login.html';
});
}
}
// 页面加载时检查登录状态
document.addEventListener('DOMContentLoaded', function() {
checkLoginStatus();
});
</script>
2025-11-27 18:32:24 +08:00
</body>
</html>